package com.ytjj.qmyx.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.aliyun.oss.OSSClient;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.kuaidi100.sdk.api.Subscribe;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.request.SubscribeParam;
import com.kuaidi100.sdk.request.SubscribeParameters;
import com.kuaidi100.sdk.request.SubscribeReq;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.kuaidi100.sdk.response.SubscribeResp;
import com.kuaidi100.sdk.utils.PropertiesReader;
import com.ytjj.common.api.CommonPage;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.constants.CopyWriterConstant;
import com.ytjj.common.constants.DateUtils;
import com.ytjj.common.enums.ExceptionOrderClassifyEnum;
import com.ytjj.common.enums.PayPayTypeEnums;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.exception.GlobalExceptionHandler;
import com.ytjj.common.model.FileResponse;
import com.ytjj.common.model.YxAlipayConfig;
import com.ytjj.common.service.AlipayService;
import com.ytjj.common.utils.*;
import com.ytjj.qmyx.admin.config.SupplyApiConfig;
import com.ytjj.qmyx.admin.constants.OrderStatusConstant;
import com.ytjj.qmyx.admin.dao.*;
import com.ytjj.qmyx.admin.eunm.*;
import com.ytjj.qmyx.admin.mapper.BillExportRecordMapper;
import com.ytjj.qmyx.admin.mapper.ExportRecordMapper;
import com.ytjj.qmyx.admin.mapper.OrdersInfoFreightMapper;
import com.ytjj.qmyx.admin.model.*;
import com.ytjj.qmyx.admin.model.dto.SonOrderDto;
import com.ytjj.qmyx.admin.model.excel.OrdersExceptionExcel;
import com.ytjj.qmyx.admin.model.excel.SpinnerWriteHandler;
import com.ytjj.qmyx.admin.model.excel.demo3.ReimbursementOrdersExcel;
import com.ytjj.qmyx.admin.model.request.*;
import com.ytjj.qmyx.admin.model.request.exportInterface.NotifyOrderInfoRequest;
import com.ytjj.qmyx.admin.model.response.*;
import com.ytjj.qmyx.admin.model.response.order.ProductInfoResponse;
import com.ytjj.qmyx.admin.model.response.order.*;
import com.ytjj.qmyx.admin.model.vo.SonOrderVO;
import com.ytjj.qmyx.admin.service.AdminService;
import com.ytjj.qmyx.admin.service.OrdersService;
import com.ytjj.qmyx.admin.service.ReturnRegisterService;
import com.ytjj.qmyx.admin.service.adapay.AdaPayService;
import com.ytjj.qmyx.admin.service.channelProductService.ChannelProductService;
import com.ytjj.qmyx.admin.utils.*;
import com.ytjj.qmyx.admin.utils.ExpressDicUtil;
import com.ytjj.qmyx.mall.client.MallClient;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.BankerRequest;
import com.ytjj.qmyx.mall.model.BankerResponse;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.users.client.OrderClient;
import com.ytjj.qmyx.users.client.UsersClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.http.entity.ContentType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 订单服务实体
 *
 *
 * @version 1.0
 *
 */
@Service
@Slf4j
@RefreshScope
public class OrdersServiceImpl implements OrdersService {

    //一个sheet装100w数据
    public static final Integer PER_SHEET_ROW_COUNT = 1000000;
    //每次查询20w数据，每次写入20w数据
    public static final Integer PER_WRITE_ROW_COUNT = 10000;


    @Resource
    private OrdersDao ordersDao;

    @Resource
    private PayConfigDao payConfigDao;

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private OrdersInfoMapper ordersInfoMapper;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;

    @Resource
    private ReturnRegisterDao returnRegisterDao;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private BankerMapper bankerMapper;

    @Resource
    private ExpressDao expressDao;

    @Autowired
    private UsersClient usersClient;

    @Autowired
    private OrderClient orderClient;

    @Resource
    private OrdersPayMapper ordersPayMapper;

    @Resource
    private BankerOrderMapper bankerOrderMapper;

    @Resource
    private ProductCategoryDao productCategoryDao;

    @Resource
    private OrderNoteDao orderNoteDao;

    @Resource
    private SupplyApiConfig supplyApiConfig;

    @Value("${excel.exportNum:30000}")
    private Integer exportNum;

    @Resource
    private UsersRealNameMapper usersRealNameMapper;

    @Resource
    private OrdersInfoFreightMapper ordersInfoFreightMapper;

    @Resource
    private ReturnGoodsDao  returnGoodsDao;

    @Autowired
    private ReturnRegisterService returnRegisterService;

    @Autowired
    private AdaPayService adaPayService;
    @Resource
    private ChannelProductService channelProductService;
    @Resource
    private ReissueLogisticsDao reissueLogisticsDao;
    @Resource
    private ExportRecordMapper exportRecordMapper;

    @Value(value = "${orderPath:}")
    private String path;
    @Resource
    private AlipayComplaintsRecordsMapper alipayComplaintsRecordsMapper;
    @Resource
    private AlipayFactoryUtils alipayFactory;
    @Resource
    private BillExportRecordMapper billExportRecordMapper;
    @Resource
    private BillExportRecordDao billExportRecordDao;
    @Resource
    private SysConfigDao sysConfigDao;

    @Autowired
    private AdminService adminService;

    /**
     * 受限制角色id(订单金额)
     */
    @Value("${limit.orderMoney.roleId:2,13}")
    private String limitOrderMoneyRoleId;

    @Resource
    private AlipayUtil alipayUtil;

    Executor pools = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024 * 1024));



    @Override
    public CommonPage getOrdersList(OrdersRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<Orders> ordersList = ordersDao.queryOrdersList(request);
        return CommonPage.restPage(ordersList);
    }

    /**
     * 获取订单列表缩减版
     *
     */
    @Override
    public CommonPage getOrdersListCurtail(OrdersRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<Orders> ordersList = ordersDao.queryOrdersListCurtail(request);
        ordersList.stream().forEach(s -> {
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(s.getId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            List<String> collect = ordersInfoList.stream().map(OrdersInfo::getChildOrderNo).collect(Collectors.toList());
            List<OrdersInfoFreightDto> ordersInfoFreightDtoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(collect)) {
                ordersInfoFreightDtoList = ordersDao.selectFreightByChildOrderNoList(collect);
            }
            AtomicReference<BigDecimal> freight = new AtomicReference<>(BigDecimal.valueOf(0));
            if (!CollectionUtils.isEmpty(ordersInfoFreightDtoList)){
                ordersInfoFreightDtoList.stream().forEach(item ->{
                    freight.set(freight.get().add(item.getFreight()));
                });
            }
            if (s.getIsPay() == 0) {
                s.setRealTotalMoney(BigDecimal.valueOf(0));
            }else {
                s.setRealTotalMoney(s.getRealTotalMoney().add(null != s.getDeductionMoney() ? s.getDeductionMoney() : BigDecimal.valueOf(0)));
            }
        });
        return CommonPage.restPage(ordersList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void writeRecord(String content, Integer orderId) {
        Orders orders = new Orders();
        orders.setId(orderId);
        orders.setSmallNote(content);
        ordersMapper.updateByPrimaryKeySelective(orders);
    }

    @Override
    public CommonPage getOrdersInfoList(OrdersInfoRequest request) {
        List<Integer> bankerIds_request = null;
        if (!StringUtils.isEmpty(request.getBankerName())) {
            Map<String, String> param = new HashMap<>();
            param.put("bankerName", request.getBankerName());
            String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/banker/getBankerIdByBankerName", param, supplyApiConfig.getHeadsMap());
            if (!StringUtils.isEmpty(resultJson)) {
                bankerIds_request = JSONArray.parseArray(resultJson, Integer.class);
            }
        }
        request.setBankerIds(bankerIds_request);
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<OrdersInfoResponse> ordersInfoResponseList = ordersDao.queryOrdersInfoList(request);
        if (!CollectionUtils.isEmpty(ordersInfoResponseList)) {
            List<Integer> bankerIds = ordersInfoResponseList.stream().map(OrdersInfoResponse::getBankerId).collect(Collectors.toList());
            Map<String, String> param = new HashMap<>();
            param.put("bankerIds", Joiner.on(",").join(bankerIds));
            String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/banker/queryBankerByIds", param, supplyApiConfig.getHeadsMap());
            CommonResult commonResult = JSONObject.parseObject(resultJson, CommonResult.class);
            List<Banker> bankerList = new ArrayList<>();
            if (200 == commonResult.getCode()) {
                bankerList = JSONArray.parseArray(commonResult.getData().toString(), Banker.class);
            }
            for (OrdersInfoResponse response : ordersInfoResponseList) {
                // 获取商品规格成本价
                if (null == response.getCostPrice()) {
                    BigDecimal specCostPrice = ordersDao.getSpecCostPrice(response.getProductId(), response.getProductSkuSpec());
                    if (null != specCostPrice) {
                        response.setCostPrice(specCostPrice);
                    } else {
                        response.setCostPrice(ordersDao.getProductCostPrice(response.getProductId()));
                    }
                }
                if (!CollectionUtils.isEmpty(bankerList)) {
                    List<Banker> matchBankers = bankerList.stream().filter(item -> item.getId().equals(response.getBankerId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(matchBankers)) {
                        response.setBankerName(matchBankers.get(0).getName());
                    }
                }

                // 处理0元测评商品
                if(response.getBankerColumnId() != null) {
                    if(response.getBankerColumnId() == 3) {
                        response.setIsZeroProduct("0元测评商品");
                    } else {
                        response.setIsZeroProduct("非0元测评商品");
                    }
                }
            }
        }
        return CommonPage.restPage(ordersInfoResponseList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> batchUpdateOrders(List<OrdersExpressRequest> list) {
        List<String> ordersIdList = new ArrayList<>();
        list.stream()
                .filter(s -> !StringUtils.isEmpty(s.getExpressNo()) && !StringUtils.isEmpty(s.getExpressCompanyNo()))
                .forEach(item -> {
                    OrdersInfoResponse info = ordersDao.queryOrdersInfoById(item.getId());
                    // 校验
                    if (null == info) {
                        ordersIdList.add(item.getChildOrderNo());
                        return;
                    }
                    if (!item.getUserPhone().equals(info.getUserPhone())) {
                        ordersIdList.add(item.getChildOrderNo());
                        return;
                    }
                    if (!item.getUserAddress().equals(info.getUserAddress())) {
                        ordersIdList.add(item.getChildOrderNo());
                        return;
                    }
                    if (!item.getUserName().equals(info.getUserName())) {
                        ordersIdList.add(item.getChildOrderNo());
                        return;
                    }
                    insertExpressOrders(item);
                    OrdersInfo ordersInfo = new OrdersInfo();
                    ordersInfo.setChildOrderNo(item.getChildOrderNo());
                    ordersInfo.setExpressCompanyNo(ExpressNameCode.getExpressCompanyNo(item.getExpressCompanyNo()));
                    ordersInfo.setExpressNo(item.getExpressNo());
                    ordersInfo.setDeliveryTime(new Date());
                    ordersInfo.setOrderinfoStatus("2");
                    ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);

                    try {
                        updateOrderExpressInfo(item.getChildOrderNo(), item.getExpressCompanyNo(), item.getExpressNo());
                    } catch (Exception e) {
                        log.error("======同步供应商快递单号异常======{}",e);
                    }

                    Orders orders = new Orders();
                    orders.setOrderStatus("2");
                    orders.setId(info.getOrderId());
                    ordersMapper.updateByPrimaryKeySelective(orders);
                    //同步订单详情的订单状态
                });
        return ordersIdList;
    }

    public void insertExpressOrders(OrdersExpressRequest item) {
        // ***** 通过校验
        // 发起快递订阅
        // 发起订阅 查询库里是否存在该快递号，如果存在，者不发起订阅，如果不存在，发起订阅
        ExpressOrdersExample expressOrdersExample = new ExpressOrdersExample();
        expressOrdersExample.createCriteria()
                .andNoEqualTo(item.getExpressNo());
        List<ExpressOrders> expressOrdersList = expressOrdersMapper.selectByExample(expressOrdersExample);
        //如果查询结果为空则新增快递信息
        if (null == expressOrdersList || expressOrdersList.size() <= 0) {
            ExpressOrders expressOrders = new ExpressOrders();
            expressOrders.setCompanyNo(ExpressNameCode.getExpressCompanyNo(item.getExpressCompanyNo()));
            expressOrders.setExpressEno(item.getExpressNo());
            expressOrders.setPhone(item.getUserPhone());
            expressOrders.setAddress(item.getUserAddress());
            expressOrders.setCreateTime(new Date());
            expressOrdersMapper.insertSelective(expressOrders);
        }
    }

    @Resource
    private ExpressOrdersMapper expressOrdersMapper;

    @Override
    public List<OrdersInfoResponse> exportOrdersExcel(OrdersInfoRequest request) {
        PageHelper.startPage(1, exportNum);
        List<OrdersInfoResponse> ordersInfoResponseList = ordersDao.queryOrdersInfoList(request);
        if (!CollectionUtils.isEmpty(ordersInfoResponseList)) {
            for (OrdersInfoResponse response : ordersInfoResponseList) {
                // 获取商品规格成本价
                if (null == response.getCostPrice()) {
                    BigDecimal specCostPrice = ordersDao.getSpecCostPrice(response.getProductId(), response.getProductSkuSpec());
                    if (null != specCostPrice) {
                        response.setCostPrice(specCostPrice);
                    } else {
                        response.setCostPrice(ordersDao.getProductCostPrice(response.getProductId()));
                    }
                }
                Product classify = productMapper.findClassify(response.getProductId());
                response.setClassifyTitle(classify.getTopCategoryTitle()+ "-" + classify.getCategoryTitle()+ "-" + classify.getBottomCategoryTitle());

                // 检验是够0元测评商品
                if(response.getBankerColumnId() != null) {
                    if(response.getBankerColumnId() == 3) {
                        response.setIsZeroProduct("0元测评商品");
                    } else {
                        response.setIsZeroProduct("非0元测评商品");
                    }
                }
                response.setActivityType(ActivityEnums.getActivityType(response.getActivityType()));
            }
        }
        return ordersInfoResponseList;
    }

    @Override
    public int updateOrderCheack(OrderCheackRequest orderCheackRequest) {
        if (CollectionUtils.isEmpty(orderCheackRequest.getOrderInfoIds())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.DERIVE_ORDER_NULL));
        }
        return ordersDao.updateOrderCheack(orderCheackRequest.getOrderInfoIds());
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void handleExpressInfo(JSONObject jsonObject) {
//        String status = jsonObject.getString("status");
//        JSONObject lastResult = jsonObject.getJSONObject("lastResult");
//        String nu = lastResult.getString("nu");
//        String com = lastResult.getString("com");
//        if ("polling".equals(status)) {
//            // 处理中
//            // 更新快递订单信息
//            ExpressOrders expressOrders = new ExpressOrders();
//            String message = jsonObject.getString("message");
//            expressOrders.setMessage(message);
//            expressOrders.setResText(jsonObject.toJSONString());
//            String ischeck = lastResult.getString("ischeck");
//            String state = lastResult.getString("state");
//            JSONArray jsonArray = lastResult.getJSONArray("data");
//            expressOrders.setInfoText(jsonArray.toJSONString());
//            expressOrders.setIsCheck(Byte.valueOf(ischeck));
//            expressOrders.setStatus(Byte.valueOf(state));
//            expressOrders.setExpressStatus(status);
//            expressOrders.setUpdateTime(new Date());
//            ExpressOrdersExample expressOrdersExample = new ExpressOrdersExample();
//            expressOrdersExample.createCriteria()
//                    .andNoEqualTo(nu);
//            expressOrdersMapper.updateByExampleSelective(expressOrders, expressOrdersExample);
//            if ("3".equals(state)) {
//                // 已签收
//                OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
//                ordersInfoExample.createCriteria()
//                        .andExpressNoEqualTo(nu);
//                OrdersInfo ordersInfo = new OrdersInfo();
//                ordersInfo.setUpdateTime(new Date());
//                //记录签收时间
//                List<QueryTrackData> queryTrackData = JSONObject.parseArray(jsonArray.toJSONString(), QueryTrackData.class);
//                if(CollectionUtils.isEmpty(queryTrackData)){
//                    ordersInfo.setReceiveTime(new Date());
//                }else {
//                    ordersInfo.setReceiveTime(DateTimeUtil.StrToTime(queryTrackData.get(0).getFtime()));
//                }
//                ordersInfo.setReceiveStatus((byte) 1);
//                //留给定时任务处理
////                ordersInfo.setOrderinfoStatus("3");
//                ordersInfoMapper.updateByExampleSelective(ordersInfo, ordersInfoExample);
//
//                // 判断订单下面的订单是否已经全部完成
//                OrdersInfoExample infoExample = new OrdersInfoExample();
//                infoExample.createCriteria()
//                        .andExpressNoEqualTo(nu);
//                List<OrdersInfo> list = ordersInfoMapper.selectByExample(infoExample);
//                List<Integer> ordersIdList = list.stream().map(item -> item.getOrderId()).distinct().collect(Collectors.toList());
//                ordersIdList.stream().forEach(item -> {
//                    OrdersInfoExample example = new OrdersInfoExample();
//                    example.createCriteria()
//                            .andOrderIdEqualTo(item)
//                            .andReceiveStatusEqualTo((byte) 0);
//                    Long count = ordersInfoMapper.countByExample(example);
//                    if (count.intValue() == 0) {
//                        // 订单已完成
//                        Orders orders = ordersMapper.selectByPrimaryKey(item);
//                        orders.setOrderStatus("3");
//                        ordersMapper.updateByPrimaryKeySelective(orders);
//                    }
//                });
//            }
//        }
//        if ("abort".equals(status)) {
//            // 中断 重新订阅
//            OrdersInfoExample example = new OrdersInfoExample();
//            example.createCriteria()
//                    .andExpressNoEqualTo(nu);
//            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(example);
//            if (null == ordersInfoList || ordersInfoList.size() <= 0) {
//                return;
//            }
//            OrdersInfo info = ordersInfoList.get(0);
//            SubscribeReq subscribeReq = new SubscribeReq();
//            subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
//            SubscribeParam subscribeParam = new SubscribeParam();
//            SubscribeParameters subscribeParameters = new SubscribeParameters();
//            subscribeParameters.setCallbackurl(PropertiesReader.get("callbackurl"));
//            subscribeParam.setParameters(subscribeParameters);
//            subscribeParam.setCompany(info.getExpressCompanyNo());
//            subscribeParam.setNumber(info.getExpressNo());
//            Orders orders = ordersMapper.selectByPrimaryKey(info.getOrderId());
//            subscribeParameters.setPhone(orders.getUserPhone());
//            subscribeParam.setKey(PropertiesReader.get("key"));
//            subscribeReq.setParam(subscribeParam);
//            Subscribe subscribe = new Subscribe();
//            subscribe.subscribe(subscribeReq);
//        }
//    }

    @Resource
    private OrdersRefundMapper refundMapper;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private MallClient mallClient;


    @Override
    //@Transactional(rollbackFor = Exception.class)
    public void refundOrders(Integer orderId, String desc) {
        // 查询订单
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        OrdersInfo ordersInfo = ordersInfoMapper.selectOrderInfoByOrderId(orderId).get(0);
        if (orders.getIsPay().byteValue() == (byte) 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_NOT_REFUND));
        }
        if (orders.getIsRefund().intValue() == 1) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.NOT_START_REFUND));
        }

        OrdersRefundExample example = new OrdersRefundExample();
        example.createCriteria()
                .andOrderNoEqualTo(orders.getOrderNo());

        List<OrdersRefund> refundList = refundMapper.selectByExample(example);
        OrdersRefund ordersRefund;
        if (refundList != null && refundList.size() > 0) {
            ordersRefund = refundList.get(0);
            if (ordersRefund.getStatus().intValue() == 1) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.APPLICATION_FOR_DRAWBACK));
            }
            if (ordersRefund.getStatus().intValue() == 2) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.NOT_START_REFUND));
            }
        } else {
            String refundNo = OrderUtils.getRefundCode(orderId);
            Integer totalFee = orders.getRealTotalMoney().multiply(new BigDecimal(100)).intValue();
            ordersRefund = new OrdersRefund();
            ordersRefund.setOrderNo(orders.getOrderNo());
            ordersRefund.setTradeNo(orders.getTradeNo());
            ordersRefund.setRefundNo(refundNo);
            ordersRefund.setTotalFee(totalFee);
            ordersRefund.setRefundFee(totalFee);
            ordersRefund.setRefundDesc(desc);
            ordersRefund.setCreateTime(new Date());
            ordersRefund.setStatus(1);
            refundMapper.insertSelective(ordersRefund);
        }
        OrdersPay ordersPay = ordersDao.queryOrdersPayByResOrderNo(orders.getTradeNo());

        handleRefundV2(orders,ordersRefund,ordersInfo,ordersPay,orderId,desc);

        /*if ("aliPay".equals(ordersPay.getTradeType())) {
            try {
                AlipayTradeRefundResponse response = alipayService.refundAliPayOrder(orders.getTradeNo(), ordersRefund.getRefundNo(),
                        ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                if (!response.getMsg().equals("Success") || !response.getCode().equals("10000")) {
                    ordersRefund.setStatus(3);
                    ordersRefund.setResText(JSONObject.toJSONString(response));
                    refundMapper.updateByPrimaryKeySelective(ordersRefund);
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED) +":" + response.getSubMsg());
                } else {
                    log.info("退款成功------------>");
                    // 退款表状态更新
                    ordersRefund.setStatus(2);
                    ordersRefund.setResText(JSONObject.toJSONString(response));
                    refundMapper.updateByPrimaryKeySelective(ordersRefund);
                    // 订单修改
                    Orders order = new Orders();
                    order.setOrderStatus("4");
                    order.setIsRefund(1);
                    order.setRefundNo(ordersRefund.getRefundNo());
                    OrdersExample ordersExample = new OrdersExample();
                    ordersExample.createCriteria()
                            .andOrderNoEqualTo(ordersRefund.getOrderNo());
                    // 订单修改
                    ordersMapper.updateByExampleSelective(order, ordersExample);
                    // 订单详情修改
                    ordersDao.updateStatusByOrderId("6", orderId);
                    //退款总状态
                    ordersMapper.updateStatus(ordersInfo.getId());
                    // 同步原路返回页退款时间
                    // 查询订单明细 (一条订单存在多条订单明细)
                    List<Integer> orderInfoIdList = ordersDao.getOrderInfoId(orderId);
                    if (!CollectionUtils.isEmpty(orderInfoIdList)) {
                        for(Integer orderInfoId : orderInfoIdList) {
                            returnRegisterDao.modifiedReturnRegister(orderInfoId);
                        }
                    }
                    try {
                        //退款退余额
                        if (null != orders.getDeductionMoney()) {
                            usersClient.addBalance(orders.getDeductionMoney(), orders.getUserId(), UserBalanceSourceEnums.REFUND.name());
                        }
                    } catch (Exception e) {
                        log.error("===退款退余额:{},{}", orders.getDeductionMoney(), orders.getUserId());
                        log.error("===退款退余额失败:{}", e);
                    }
                }
            } catch (ApiException e) {
                throw e;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Map<String, String> response = new HashMap<>();
            if("ISV_JSAPI".equalsIgnoreCase(ordersPay.getTradeType())){//服务商模式
                response = orderClient.refundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                        ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
            }else {
                if("H5-JSAPI".equals(ordersPay.getTradeType())){
                    response = mallClient.h5RefundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                            ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                }
                if (orders.getOrderSource().equals("h5")) {
                    response = mallClient.h5RefundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                            ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                } else {
                    response = mallClient.refundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                            ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                }
            }
            if (!StringUtils.isEmpty(response.get("return_code")) && !response.get("return_code").equals("SUCCESS")) {
                ordersRefund.setStatus(3);
                ordersRefund.setResText(JSONObject.toJSONString(response));
                refundMapper.updateByPrimaryKeySelective(ordersRefund);
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED) +":"+ response.get("return_msg"));
            }
            if (!StringUtils.isEmpty(response.get("return_code")) && !response.get("result_code").equals("SUCCESS")) {
                ordersRefund.setStatus(3);
                ordersRefund.setResText(JSONObject.toJSONString(response));
                refundMapper.updateByPrimaryKeySelective(ordersRefund);
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED) +":" + response.get("err_code_des"));
            }

            ordersRefund.setStatus(2);
            ordersRefund.setResText(JSONObject.toJSONString(response));
            refundMapper.updateByPrimaryKeySelective(ordersRefund);
            // 订单修改
            Orders order = new Orders();
            order.setOrderStatus("4");
            order.setIsRefund(1);
            order.setRefundNo(ordersRefund.getRefundNo());
            OrdersExample ordersExample = new OrdersExample();
            ordersExample.createCriteria()
                    .andOrderNoEqualTo(ordersRefund.getOrderNo());
            ordersMapper.updateByExampleSelective(order, ordersExample);
            ordersDao.updateStatusByOrderId("6", orderId);

            try {
                //退款退余额
                if (null != orders.getDeductionMoney()) {
                    usersClient.addBalance(orders.getDeductionMoney(), orders.getUserId(), UserBalanceSourceEnums.REFUND.name());
                }
            } catch (Exception e) {
                log.error("===退款退余额:{},{}", orders.getDeductionMoney(), orders.getUserId());
                log.error("===退款退余额失败:{}", e);
            }

            // 查询订单明细 (一条订单存在多条订单明细)
            List<Integer> orderInfoIdList = ordersDao.getOrderInfoId(orderId);
            if (!CollectionUtils.isEmpty(orderInfoIdList)) {
                for(Integer orderInfoId : orderInfoIdList) {
                    log.info("修改原路返回页开始, {}------------>", orderId);
                    returnRegisterDao.modifiedReturnRegister(orderInfoId);
                    log.info("修改原路返回页结束, {} ------------>", orderInfoId);
                }
            }
        }*/
    }
//    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handleRefundV2(Orders orders,OrdersRefund ordersRefund,OrdersInfo ordersInfo,OrdersPay ordersPay,Integer orderId,String desc){
        if ("aliPay".equals(ordersPay.getTradeType())) {
            try {
                AlipayTradeRefundResponse response = alipayService.refundAliPayOrder(orders.getTradeNo(), ordersRefund.getRefundNo(),
                        ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc,ordersPay.getChildId());
                if (!response.getMsg().equals("Success") || !response.getCode().equals("10000")) {
                    ordersRefund.setStatus(3);
                    ordersRefund.setResText(JSONObject.toJSONString(response));
                    refundMapper.updateByPrimaryKeySelective(ordersRefund);
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED) +":" + response.getSubMsg());
                } else {
                    log.info("退款成功------------>");
                    // 退款表状态更新
                    ordersRefund.setStatus(2);
                    ordersRefund.setResText(JSONObject.toJSONString(response));
                    refundMapper.updateByPrimaryKeySelective(ordersRefund);
                    // 订单修改
                    Orders order = new Orders();
                    order.setOrderStatus("4");
                    order.setIsRefund(1);
                    order.setRefundNo(ordersRefund.getRefundNo());
                    OrdersExample ordersExample = new OrdersExample();
                    ordersExample.createCriteria()
                            .andOrderNoEqualTo(ordersRefund.getOrderNo());
                    // 订单修改
                    ordersMapper.updateByExampleSelective(order, ordersExample);
                    // 订单详情修改
                    ordersDao.updateStatusByOrderId("6", orderId);
                    //退款总状态
                    ordersMapper.updateStatus(ordersInfo.getId());
                    // 同步原路返回页退款时间
                    // 查询订单明细 (一条订单存在多条订单明细)
                    List<Integer> orderInfoIdList = ordersDao.getOrderInfoId(orderId);
                    if (!CollectionUtils.isEmpty(orderInfoIdList)) {
                        for(Integer orderInfoId : orderInfoIdList) {
                            returnRegisterDao.modifiedReturnRegister(orderInfoId);
                        }
                    }
                    try {
                        //退款退余额
                        if (null != orders.getDeductionMoney()) {
                            usersClient.addBalance(orders.getDeductionMoney(), orders.getUserId(), UserBalanceSourceEnums.REFUND.name());
                        }
                    } catch (Exception e) {
                        log.error("===退款退余额:{},{}", orders.getDeductionMoney(), orders.getUserId());
                        log.error("===退款退余额失败:{}", e);
                    }
                }
            } catch (ApiException e) {
                throw e;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Map<String, String> response = new HashMap<>();
            if("ISV_JSAPI".equalsIgnoreCase(ordersPay.getTradeType())){//服务商模式
                response = orderClient.refundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                        ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
            }else {
                if("H5-JSAPI".equals(ordersPay.getTradeType())){
                    response = mallClient.h5RefundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                            ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                }
                if (orders.getOrderSource().equals("h5")) {
                    response = mallClient.h5RefundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                            ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                } else {
                    response = mallClient.refundOrders(ordersPay.getTradeType(), orders.getTradeNo(), ordersRefund.getRefundNo(),
                            ordersRefund.getTotalFee(), ordersRefund.getRefundFee(), desc);
                }
            }
            if (!"SUCCESS".equals(response.get("return_code")) &&!"PROCESSING".equals(response.get("return_code"))) {
                ordersRefund.setStatus(3);
                ordersRefund.setResText(JSONObject.toJSONString(response));
                refundMapper.updateByPrimaryKeySelective(ordersRefund);
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED) +":"+ response.get("return_msg"));
            }
            if (!"SUCCESS".equals(response.get("return_code")) &&!"PROCESSING".equals(response.get("return_code"))) {
                ordersRefund.setStatus(3);
                ordersRefund.setResText(JSONObject.toJSONString(response));
                refundMapper.updateByPrimaryKeySelective(ordersRefund);
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED) +":" + response.get("err_code_des"));
            }

            ordersRefund.setStatus(2);
            ordersRefund.setResText(JSONObject.toJSONString(response));
            refundMapper.updateByPrimaryKeySelective(ordersRefund);
            // 订单修改
            Orders order = new Orders();
            order.setOrderStatus("4");
            order.setIsRefund(1);
            order.setRefundNo(ordersRefund.getRefundNo());
            OrdersExample ordersExample = new OrdersExample();
            ordersExample.createCriteria()
                    .andOrderNoEqualTo(ordersRefund.getOrderNo());
            ordersMapper.updateByExampleSelective(order, ordersExample);
            ordersDao.updateStatusByOrderId("6", orderId);

            try {
                //退款退余额
                if (null != orders.getDeductionMoney()) {
                    usersClient.addBalance(orders.getDeductionMoney(), orders.getUserId(), UserBalanceSourceEnums.REFUND.name());
                }
            } catch (Exception e) {
                log.error("===退款退余额:{},{}", orders.getDeductionMoney(), orders.getUserId());
                log.error("===退款退余额失败:{}", e);
            }

            // 查询订单明细 (一条订单存在多条订单明细)
            List<Integer> orderInfoIdList = ordersDao.getOrderInfoId(orderId);
            if (!CollectionUtils.isEmpty(orderInfoIdList)) {
                for(Integer orderInfoId : orderInfoIdList) {
                    log.info("修改原路返回页开始, {}------------>", orderId);
                    returnRegisterDao.modifiedReturnRegister(orderInfoId);
                    log.info("修改原路返回页结束, {} ------------>", orderInfoId);
                }
            }
        }
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleRefund(Map<String, String> notifyMap) {
        String refundStatus = notifyMap.get("refund_status");//商户订单号
        String outRefundNo = notifyMap.get("out_refund_no");
        OrdersRefundExample ordersRefundExample = new OrdersRefundExample();
        ordersRefundExample.createCriteria()
                .andRefundNoEqualTo(outRefundNo);
        List<OrdersRefund> ordersRefundList = refundMapper.selectByExample(ordersRefundExample);

        if (null == ordersRefundList && ordersRefundList.size() <= 0) {
            log.warn("微信退款，没有找到该订单号：{}", outRefundNo);
            return;
        }
        if ("SUCCESS".equals(refundStatus)) {
            // 成功
            // 将订单状态改成已退款
            OrdersRefund ordersRefund = ordersRefundList.get(0);
            // 将退款订单改成退款成功，并且记录
            if (ordersRefund.getStatus().intValue() == 2) {
                return;
            }
            ordersRefund.setStatus(2);
            ordersRefund.setResText(JSONObject.toJSONString(notifyMap));
            ordersRefund.setUpdateTime(new Date());
            refundMapper.updateByPrimaryKeySelective(ordersRefund);

            Orders orders = new Orders();
            orders.setOrderStatus("6");
            orders.setIsRefund(1);
            orders.setRefundNo(outRefundNo);

            OrdersExample example = new OrdersExample();
            example.createCriteria()
                    .andOrderNoEqualTo(ordersRefund.getOrderNo());
            ordersMapper.updateByExampleSelective(orders, example);
            Orders orders1 = ordersDao.getProductIdByOrderNo(ordersRefund.getOrderNo());
            if (orders1 != null) {
                ordersDao.updateStatusByOrderId("6", orders1.getId());
            }
            // 同步原路返回页退款时间
            returnRegisterDao.updateRefundTime(ordersRefund.getOrderNo());

        } else {
            OrdersRefund ordersRefund = ordersRefundList.get(0);
            // 失败
            ordersRefund.setStatus(3);
            ordersRefund.setResText(JSONObject.toJSONString(notifyMap));
            ordersRefund.setUpdateTime(new Date());
            refundMapper.updateByPrimaryKeySelective(ordersRefund);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCourier(CourierInfosRequest courierInfosRequest) {

        OrdersInfo ordersInfo = Optional.ofNullable(ordersInfoMapper.selectByPrimaryKey(courierInfosRequest.getId()))
                .orElseThrow(() -> new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_ID_NOT_EXIST)));
        // 如果快递单号 跟 快递公司编号为空 则 只更新地址
        if(StringUtils.isEmpty(courierInfosRequest.getExpressNo()) || StringUtils.isEmpty(courierInfosRequest.getExpressCompanyNo())){
            Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
            orders.setUserAddress(courierInfosRequest.getUserAddress());
            ordersMapper.updateByPrimaryKeySelective(orders);
        }else{
            // 查询快递是否已经录入过
            ExpressOrdersExample expressOrdersExample = new ExpressOrdersExample();
            expressOrdersExample.createCriteria()
                    .andNoEqualTo(courierInfosRequest.getExpressNo());
            Long count = expressOrdersMapper.countByExample(expressOrdersExample);
            Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());
            orders.setUserAddress(courierInfosRequest.getUserAddress());
            orders.setOrderStatus("2");                             // 已发货
            ordersMapper.updateByPrimaryKeySelective(orders);
            if (count > 0) {
                ordersInfo.setExpressNo(courierInfosRequest.getExpressNo());
                ordersInfo.setExpressCompanyNo(courierInfosRequest.getExpressCompanyNo());
                ordersInfo.setOrderinfoStatus("2");
                ordersInfo.setDeliveryTime(new Date());
                ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);

                try {
                    updateOrderExpressInfo(ordersInfo.getChildOrderNo(), courierInfosRequest.getExpressCompanyNo(), courierInfosRequest.getExpressNo());
                } catch (Exception e) {
                    log.error("======同步供应商快递单号异常1======{}",e);
                }
                return;
            }
            // 发起订阅
            SubscribeReq subscribeReq = new SubscribeReq();
            subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
            SubscribeParam subscribeParam = new SubscribeParam();
            SubscribeParameters subscribeParameters = new SubscribeParameters();
            subscribeParameters.setCallbackurl(PropertiesReader.get("callbackurl"));
            subscribeParam.setParameters(subscribeParameters);
            subscribeParam.setCompany(courierInfosRequest.getExpressCompanyNo());
            subscribeParam.setNumber(courierInfosRequest.getExpressNo());
            subscribeParameters.setPhone(orders.getUserPhone());
            subscribeParam.setKey(PropertiesReader.get("key"));
            subscribeReq.setParam(subscribeParam);
            Subscribe subscribe = new Subscribe();
            SubscribeResp subscribeResp = subscribe.subscribe(subscribeReq);
            if (!subscribeResp.isResult()) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SUBSCRIBE_TO_EXPRESS_FAILED)+ subscribeResp.getMessage());
            }

            insertExpressOrders(courierInfosRequest.getExpressCompanyNo(), courierInfosRequest.getExpressNo(), orders.getUserPhone(), orders.getUserAddress());

            ordersInfo.setExpressNo(courierInfosRequest.getExpressNo());
            ordersInfo.setExpressCompanyNo(courierInfosRequest.getExpressCompanyNo());
            ordersInfo.setUpdateTime(new Date());
            ordersInfo.setDeliveryTime(new Date());
            ordersInfo.setIsExport((byte)1);
            ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
            String response = updateOrderExpressInfo(ordersInfo.getChildOrderNo(), courierInfosRequest.getExpressCompanyNo(), courierInfosRequest.getExpressNo());
            CommonResult commonResult = JSONObject.parseObject(response, CommonResult.class);
            if (commonResult.getCode() != 200) {
                throw new ApiException("同步供应商快递单号异常：" + commonResult.getMessage());
            }
        }

    }

    @Override
    public String updateOrderExpressInfo(String childOrderNo, String expressCompanyNo, String expressNo) {
        OrderExpressModifiedRequest orderExpressModifiedRequest = new OrderExpressModifiedRequest();
        orderExpressModifiedRequest.setChildOrderNo(childOrderNo);
        orderExpressModifiedRequest.setExpressCompany(expressCompanyNo);
        orderExpressModifiedRequest.setExpressNo(expressNo);
        orderExpressModifiedRequest.setShopId(supplyApiConfig.getShopId());
        String json = JSON.toJSONString(orderExpressModifiedRequest);
        String s = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/updateOrderExpressInfo", json, supplyApiConfig.getHeadsMap());
        return s;
    }

    @Override
    public CommonResult updateWxAppOrdersStatus() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(new Date());
        String dateStr = format + " 08:00:00";
        List<OrdersPay> payList = ordersDao.getWxAppOrdersPayList(dateStr);
        payList.stream().forEach(item -> {
            try {
                Map<String, String> map = mallClient.wxAppOrderQuery(item.getResOrderNo(), item.getTradeType());
                if ("SUCCESS".equals(map.get("trade_state"))) {
                    map.put("trade_type", item.getTradeType());
                    mallClient.updateOrdersPay(map);
                } else if ("USERPAYING".equals(map.get("trade_state"))) {

                } else if ("CLOSED".equals("trade_state")) {

                } else {
                    // 失败或者不支付
                    item.setPayType(PayPayTypeEnums.FAIL.getType());
                    item.setResText(JSONObject.toJSONString(map));
                    ordersPayMapper.updateByPrimaryKeyWithBLOBs(item);
                }

            } catch (Exception e) {
                e.printStackTrace();
                log.error("查询订单发生异常：e:{}", GlobalExceptionHandler.getExceptionToString(e));
            }
        });
        return CommonResult.success();
    }

    @Override
    public CommonResult updateAliPayAppOrdersStatus() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(new Date());
        String dateStr = format + " 08:00:00";
        List<OrdersPay> payList = ordersDao.getAliPayAppOrdersPayList(dateStr);
        payList.stream().forEach(item -> {
            try {
                AlipayTradeQueryResponse response = alipayService.AliPayAppOrderQueryByCert(item.getResOrderNo(), "");
                log.info("getOutTradeNo={}", response.getOutTradeNo());
                if ("10000".equals(response.getCode())) {
                    log.info("response.getMsg()={}", response.getMsg());
                    if ("Success".equalsIgnoreCase(response.getMsg())) {
                        String state = response.getTradeStatus();
                        log.info("response.getTradeStatus()={}", response.getTradeStatus());
                        if ("TRADE_SUCCESS".equals(state)) {
                            // 成功
                            mallClient.updateAliPayOrdersPay(response);
                        }
                        if ("TRADE_CLOSED".equals(state)) {
                            // 失败或者不支付
                            item.setPayType(PayPayTypeEnums.FAIL.getType());
                            item.setResText(JSONObject.toJSONString(response));
                            ordersPayMapper.updateByPrimaryKeyWithBLOBs(item);
                        }
                    } else {
                        log.warn("查询订单失败----------->");
                    }
                } else {
                    if ("40004".equals(response.getCode())) {
                        // 订单不存在
                        item.setPayType(PayPayTypeEnums.FAIL.getType());
                        item.setResText(JSONObject.toJSONString(response));
                        ordersPayMapper.updateByPrimaryKeyWithBLOBs(item);
                    } else {
                        // 查询失败
                        log.warn("订单查询失败：outOrderNo:{}", item.getResOrderNo());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("查询订单发生异常：e:{}", GlobalExceptionHandler.getExceptionToString(e));
            }
        });
        return CommonResult.success();
    }

    private int insertExpressOrders(String expressCompanyNo, String expressEno, String userPhone, String userAddress) {
        ExpressOrders expressOrders = new ExpressOrders();
        expressOrders.setCompanyNo(expressCompanyNo);
        expressOrders.setExpressEno(expressEno);
        expressOrders.setPhone(userPhone);
        expressOrders.setAddress(userAddress);
        expressOrders.setCreateTime(new Date());
        String json = JSON.toJSONString(expressOrders);
        String s = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/insertExpressOrder", json, supplyApiConfig.getHeadsMap());
        CommonResult result = JSONObject.parseObject(s, CommonResult.class);
        return (int)result.getCode();
    }

    @Override
    public void editOrdersStatus(Integer orderId, String orderStatus) {
        Orders orders = new Orders();
        orders.setId(orderId);
        orders.setOrderStatus(orderStatus);
        ordersMapper.updateByPrimaryKeySelective(orders);
        ordersDao.updateStatusByOrderId(orderStatus, orderId);
    }

    @Override
    public List<Orders> getAllOrder() {
        return ordersDao.getAllOrder();
    }

    @Override
    public List<OrdersInfo> getAllOrdersInfoByOrderId(Integer orderId) {
        return ordersDao.getAllOrdersInfoByOrderId(orderId);
    }

    @Override
    public Integer updateStatusByOrderId(String ordersinfoStatus, Integer orderId) {
        return ordersDao.updateStatusByOrderId(ordersinfoStatus, orderId);
    }

    @Override
    public OrderDetailResponse getOrderDetail(Integer orderId) {
        OrderResponse orderResponse = this.getOrderByOrderId(orderId);

        OrderDetailResponse orderDetailResponse = new OrderDetailResponse();

        // 支付信息
        OrderPayResponse orderPay = this.getOrderPay(orderResponse);
        // 订单信息
        OrderInfoResponse orderInfo = this.getOrderInfo(orderResponse);
        // 物流信息
        ExpressInfoResponse expressInfo = this.getExpressInfo(orderResponse);
        // 商品信息
        List<ProductInfoResponse> productInfoList = new ArrayList<>();
        // 优惠信息
        List<OrderDiscountsResponse> orderDiscountsList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderResponse.getOrdersInfoList())) {
            for (OrdersInfo response : orderResponse.getOrdersInfoList()) {

                Integer productId = response.getProductId();
                Product product = productMapper.selectByPrimaryKey(productId);
                OrdersSpec productSpec = productMapper.selectSpecs(orderId);

                // 商品信息
                ProductInfoResponse productInfo = this.getProductInfo(orderResponse, product,productSpec);
                productInfoList.add(productInfo);

                // 优惠信息
                OrderDiscountsResponse orderDiscounts = this.getOrderDiscounts(orderResponse, product,productSpec);
                orderDiscountsList.add(orderDiscounts);
            }
        }

        return orderDetailResponse.setOrderPayResponse(orderPay)
                .setProductInfoResponse(productInfoList)
                .setOrderInfoResponse(orderInfo)
                .setExpressInfoResponse(expressInfo)
                .setOrderDiscountsResponse(orderDiscountsList);
    }

    /**
     * 获取订单详情缩减版
     */
    @Override
    public OrderDetailResponse getOrderDetailCurtail(Integer orderId) {
        OrderResponse orderResponse = this.getOrderByOrderIdCurtail(orderId);

        OrderDetailResponse orderDetailResponse = new OrderDetailResponse();

        // 支付信息
        OrderPayResponse orderPay = this.getOrderPay(orderResponse);
        // 订单信息
        OrderInfoResponse orderInfo = this.getOrderInfoCut(orderResponse);
        // 物流信息
        ExpressInfoResponse expressInfo = this.getExpressInfoCut(orderResponse);
        // 商品信息
        List<ProductInfoResponse> productInfoList = new ArrayList<>();
        // 优惠信息
        List<OrderDiscountsResponse> orderDiscountsList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderResponse.getOrdersInfoList())) {
            for (OrdersInfo response : orderResponse.getOrdersInfoList()) {

                Integer productId = response.getProductId();
                Product product = productMapper.selectByPrimaryKey(productId);
                OrdersSpec productSpec = productMapper.selectSpecs(orderId);

                // 商品信息
                ProductInfoResponse productInfo = this.getProductInfoCut(orderResponse, product,null == productSpec? null : productSpec);
                productInfoList.add(productInfo);

                // 优惠信息
                OrderDiscountsResponse orderDiscounts = this.getOrderDiscountsCut(orderResponse, product,null == productSpec? null : productSpec);
                orderDiscountsList.add(orderDiscounts);
            }
        }

        return orderDetailResponse.setOrderPayResponse(orderPay)
                .setProductInfoResponse(productInfoList)
                .setOrderInfoResponse(orderInfo)
                .setExpressInfoResponse(expressInfo)
                .setOrderDiscountsResponse(orderDiscountsList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderInfo(OrderAddressRequest orderAddressRequest) {
        ordersDao.updateOrderInfo(orderAddressRequest);
        ordersDao.updateOrders(orderAddressRequest);
    }

    @Override
    public List<ExpressDic> getExpressDicList() {
        return ordersDao.getExpressDicList();
    }

    @Override
    public List<TwoOrdersResponse> getTwoOrdersList(OrdersRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        return ordersDao.queryTwoOrdersList(request);
    }

    @Override
    public List<TwoOrdersResponse> batchExportTwoOrderList(OrdersRequest request) {
        return ordersDao.queryTwoOrdersList(request);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchInsertOrders(List<TwoOrderRequest> twoOrderRequestList) {
        twoOrderRequestList.stream()
                .forEach(item -> {
                    ordersDao.updateOrderExpress(item);
                    ordersDao.updateOrderStatus(item.getId());
                });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int InsertOrders(List<NewImportOrderRequest> newImportOrderRequest) {
        List<NewImportOrderRequest> list = newImportOrderRequest
                .stream()
                .filter(s -> null != s.getExpressNo() && s.getOrderStatus().equals("待发货") || s.getOrderStatus().equals("已发货"))
                .map(item -> {
                    item.setExpressCompanyNo(ExpressNameCode.getExpressCompanyNo(item.getExpressCompanyNo()));
                    return item;
                }).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(list)) {
            return 0;
        }
        list.stream().forEach(item -> {
            boolean b = ordersDao.updateExpressById(item.getExpressCompanyNo(), item.getExpressNo(), item.getOrderInfoId());
            if (b) {
                ordersDao.updateOrderStatusByOrderNo(item.getOrderNo());
                updateOrderExpressInfo(item.getChildOrderNo(),item.getExpressCompanyNo(),item.getExpressNo());
            }
        });
        return list.size();
    }

    private void accept(NewImportOrderRequest item) {
        OrdersInfo info = ordersInfoMapper.selectByPrimaryKey(Integer.valueOf(item.getOrderInfoId()));
        String expressCompanyNoCode = ExpressNameCode.getExpressCompanyNo(item.getExpressCompanyNo());
        // 修改OrderInfo_status = 2 并插入快递单号和快递公司
        OrdersInfo ordersInfo = new OrdersInfo();
        ordersInfo.setId(Integer.valueOf(item.getOrderInfoId()));
        ordersInfo.setExpressCompanyNo(expressCompanyNoCode);
        ordersInfo.setExpressNo(item.getExpressNo());
        ordersInfo.setDeliveryTime(new Date());
        ordersInfo.setOrderinfoStatus("2");
        ordersInfo.setIsExport((byte) 1);
        BankerOrder bankerOrder = new BankerOrder();
        bankerOrder.setExpressCode(expressCompanyNoCode);
        bankerOrder.setExpressNo(item.getExpressNo());
        bankerOrder.setChildOrderNo(info.getChildOrderNo());
        bankerOrderMapper.SynchronizeExpress(bankerOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean fillOrderExpress(Integer orderId, String expressCompanyNo, String expressNo,Integer orderInfoId) {
        return ordersDao.fillOrderExpress(orderId, expressCompanyNo, expressNo,orderInfoId);
    }

    @Override
    public boolean insertExpress(Integer orderId, String expressCompanyNo, String expressNo,Integer orderInfoId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        int count = insertExpressOrders(expressCompanyNo, expressNo, orders.getUserPhone(), orders.getUserAddress());
        return count > 0 ? true : false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean fillOrder(String expressCompanyNo, String expressNo, String express,Integer orderInfoId) {
        return ordersDao.fillOrder(expressCompanyNo,expressNo,express,orderInfoId);
    }

    /**
     * 获取订单明细列表缩减版
     */
    @Override
    public CommonPage getOrdersInfoListCurtail(OrdersInfoRequest request) {
        if (null != request.getOrderSource() && request.getOrderSource().equals("weapp")){
            request.setOrderSource("ISV-JSAPI");
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<OrdersInfoResponse> ordersInfoResponseList = ordersDao.queryOrdersInfoListCurtail(request);
        if (CollectionUtils.isEmpty(ordersInfoResponseList)) {
            return CommonPage.restPage(new ArrayList<>());
        }
        List<Integer> orderInfoIds = ordersInfoResponseList.stream().map(OrdersInfoResponse::getId).collect(Collectors.toList());

        //运费
        List<String> childOrderNoList = ordersInfoResponseList.stream().map(OrdersInfoResponse::getChildOrderNo).collect(Collectors.toList());
        List<OrdersInfoFreightDto> ordersInfoFreightDtoList = ordersDao.selectFreightByChildOrderNoList(childOrderNoList);

        List<String> orderInfoIdss = new ArrayList<>();
        orderInfoIds.stream().forEach(s -> {
            orderInfoIdss.add("YTJJ" + s);
            orderInfoIdss.add("QMYX" + s);
        });
        List<Integer> productIdList = ordersInfoResponseList.stream().filter(item -> null != item.getProductId()).map(OrdersInfoResponse::getProductId).collect(Collectors.toList());
        ProductExample example = new ProductExample();
        example.createCriteria().andIdIn(productIdList);
        List<Product> products = productMapper.selectByExample(example);

        List<Integer> bankerIds = ordersInfoResponseList.stream().filter(item ->null != item.getBankerId()).map(OrdersInfoResponse::getBankerId).collect(Collectors.toList());
        //查询供应商名称
        BankerRequest bankerRequest = new BankerRequest();
        bankerRequest.setBankerIdList(bankerIds);
        String json = JSON.toJSONString(bankerRequest);
        String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/product/getBankerMsg", json, supplyApiConfig.getHeadsMap());
        List<BankerResponse> bankerResponses = JSONObject.parseArray(result, BankerResponse.class);


        ordersInfoResponseList.forEach(ordersInfoResponse ->{
            List<OrdersInfoFreightDto> collect1 = ordersInfoFreightDtoList.stream().filter(item -> item.getChildOrderNo().equals(ordersInfoResponse.getChildOrderNo())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect1)){
                //运费
                ordersInfoResponse.setFreight(collect1.get(0).getFreight());
            }

            List<BankerResponse> collect = bankerResponses.stream().filter(item -> item.getBankerId().equals(ordersInfoResponse.getBankerId())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)){
                //供应商名称
                ordersInfoResponse.setBankerName(collect.get(0).getBankerName());
            }
            //供应链商品id
            if (!com.alibaba.excel.util.CollectionUtils.isEmpty(products)) {
                List<Product> collect2 = products.stream().filter(item -> item.getId().equals(ordersInfoResponse.getProductId())).collect(Collectors.toList());
                ordersInfoResponse.setSupplyProductId(com.alibaba.excel.util.CollectionUtils.isEmpty(collect2) ? 0 : collect2.get(0).getSupplyProductId());
            }

        });
        if (!CollectionUtils.isEmpty(ordersInfoResponseList)) {
            ordersInfoResponseList.stream().forEach(item -> {
                item.setIsZeroProduct("非0元测评商品");
                if (ActivityEnums.ZERO_EVALUATION.getActivityCode().equals(item.getActivityType())) {
                    item.setIsZeroProduct("0元测评商品");
                }
                // 未支付订单设为null
                if (item.getIsPay() == 0) {
                    item.setPayPrice(null);
                } else {
                    item.setPayPrice(item.getRealTotalMoney());
                }
            });
        }
        return CommonPage.restPage(ordersInfoResponseList);
    }

    public OrderPayResponse getOrderPay(OrderResponse orderResponse) {
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        Orders orders = orderResponse.getOrders();
        String expressNo = orderResponse.getOrdersInfoList().get(0).getExpressNo();
        Date receiveTime = orderResponse.getOrdersInfoList().get(0).getReceiveTime();
        orderPayResponse.setBuyerMessage(orders.getOrderRemarks());
        orderPayResponse.setOrderStatus(OrderStatusEnums.getStatusDesc(orders.getOrderStatus()));
        orderPayResponse.setStatus(OrderStatusConstant.CREATE_ORDER);
        if(orders.getIsPay() == 1) {
            orderPayResponse.setStatus(OrderStatusConstant.PAY);
        }
        if(!StringUtils.isEmpty(expressNo)) {
            orderPayResponse.setStatus(OrderStatusConstant.DELIVERY);
        }
        if(receiveTime != null || orders.getOrderStatus().equals(OrderStatusConstant.ORDER_FINISH)) {
            orderPayResponse.setStatus(OrderStatusConstant.RECEIVE);
        }
        return orderPayResponse;
    }

    /**
     * 根据订单ID查询订单
     * @param orderId
     * @return
     */
    public OrderResponse getOrderByOrderId(Integer orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        List<OrdersInfo> orderInfoList = ordersDao.getOrderInfoList(orderId);
        OrderResponse orderResponse = new OrderResponse();
        orderResponse.setOrders(orders);
        orderResponse.setOrdersInfoList(orderInfoList);
        return orderResponse;
    }

    /**
     * 根据订单ID查询订单缩减版
     * @param orderId
     * @return
     */
    public OrderResponse getOrderByOrderIdCurtail(Integer orderId) {
        Orders orders = ordersMapper.selectById(orderId);
        List<OrdersInfo> orderInfoList = ordersDao.getOrderInfoList(orderId);
        OrderResponse orderResponse = new OrderResponse();
        orderResponse.setOrders(orders);
        orderResponse.setOrdersInfoList(orderInfoList);
        return orderResponse;
    }

    /**
     * 商品信息
     */
    public ProductInfoResponse getProductInfo(OrderResponse orderResponse, Product product,OrdersSpec productSpec) {
        ProductInfoResponse productInfoResponse = new ProductInfoResponse();
        Banker banker = bankerMapper.selectByPrimaryKey(product.getBankerId());
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        productInfoResponse.setProductId(product.getId());
        productInfoResponse.setBankerName(banker.getName());
        productInfoResponse.setProductName(product.getProductName());
        productInfoResponse.setProductImg(product.getProductImg());
        productInfoResponse.setProductCostPrice(productSpec.getCostPrice());
        //1
        productInfoResponse.setProductOriginalPrice(productSpec.getOriginalPrice());
        productInfoResponse.setProductPrice(product.getPrice() + "元");
        // 商品售价
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_SCORE.name())) {
            //2
            productInfoResponse.setProductPrice(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "积分+" + productSpec.getPrice() + "元");
        }
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_COUPON.name())) {
            productInfoResponse.setProductPrice(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "优惠券+" + product.getPrice() + "元");
        }
        // 商品活动
        productInfoResponse.setActivityType(ActivityTypeNameCode.getName(ordersInfo.getActivityType()));
        if(product.getIsZeroProduct() == 1) {
            productInfoResponse.setActivityType("测评商品");
        }
        // 商品数量
        productInfoResponse.setProductNum("x " + orderResponse.getOrdersInfoList().size());
        // 商品规格
        productInfoResponse.setProductSpec(ordersInfo.getProductSkuSpec());
        // 商品三级分类
        if (product.getTopCategoryId() != null) {
            productInfoResponse.setTopCategoryTitle(productCategoryDao.getTitleById(product.getTopCategoryId()));
        }
        if (product.getCategoryId() != null) {
            productInfoResponse.setCategoryTitle(productCategoryDao.getTitleById(product.getCategoryId()));
        }
        if (product.getBottomCategoryId() != null) {
            productInfoResponse.setBottomCategoryTitle(productCategoryDao.getTitleById(product.getBottomCategoryId()));
        }
        return productInfoResponse;
    }

    /**
     * 商品信息
     */
    public ProductInfoResponse getProductInfoCut(OrderResponse orderResponse, Product product,OrdersSpec productSpec) {
        ProductInfoResponse productInfoResponse = new ProductInfoResponse();
        Banker banker = bankerMapper.selectByPrimaryKey(product.getBankerId());
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        productInfoResponse.setProductId(product.getId());
        productInfoResponse.setBankerName(banker.getName());
        productInfoResponse.setProductName(product.getProductName());
        productInfoResponse.setProductImg(product.getProductImg());
        productInfoResponse.setProductCostPrice(null);
        //1
        productInfoResponse.setProductOriginalPrice(null == productSpec ? null : productSpec.getOriginalPrice());
        productInfoResponse.setProductPrice(product.getPrice() + "元");
        // 商品售价
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_SCORE.name())) {
            //2
            productInfoResponse.setProductPrice(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "积分+" +( null == productSpec ? null :productSpec.getPrice()) + "元");
        }
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_COUPON.name())) {
            productInfoResponse.setProductPrice(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "优惠券+" + product.getPrice() + "元");
        }
        // 商品活动
        productInfoResponse.setActivityType(ActivityTypeNameCode.getName(ordersInfo.getActivityType()));
        if(product.getIsZeroProduct() == 1) {
            productInfoResponse.setActivityType("测评商品");
        }
        // 商品数量
        productInfoResponse.setProductNum("x " + orderResponse.getOrdersInfoList().size());
        // 商品规格
        productInfoResponse.setProductSpec(ordersInfo.getProductSkuSpec());
        // 商品三级分类
        if (product.getTopCategoryId() != null) {
            productInfoResponse.setTopCategoryTitle(productCategoryDao.getTitleById(product.getTopCategoryId()));
        }
        if (product.getCategoryId() != null) {
            productInfoResponse.setCategoryTitle(productCategoryDao.getTitleById(product.getCategoryId()));
        }
        if (product.getBottomCategoryId() != null) {
            productInfoResponse.setBottomCategoryTitle(productCategoryDao.getTitleById(product.getBottomCategoryId()));
        }
        return productInfoResponse;
    }

    /**
     * 订单信息
     */
    public OrderInfoResponse getOrderInfo(OrderResponse orderResponse) {
        OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
        Orders orders = orderResponse.getOrders();
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        orderInfoResponse.setOrderNo(orders.getOrderNo());
        orderInfoResponse.setOrderInfoId(ordersInfo.getId());
        orderInfoResponse.setPayChannel(orders.getOrderSource());
        orderInfoResponse.setPayPhone(orders.getTel());
        orderInfoResponse.setCreateOrderTime(orders.getCreateTime());
        orderInfoResponse.setPayType(orders.getPaySource());
        orderInfoResponse.setPayTime(orders.getPayTime());
        orderInfoResponse.setPayOrderNo(orders.getTradeNo());
        // 签收时间
        orderInfoResponse.setReceiveTime(ordersInfo.getReceiveTime());
        // 是否导出订单
        orderInfoResponse.setIsExportOrder(ordersInfo.getIsExport());
        return orderInfoResponse;
    }

    /**
     * 订单信息缩减版
     */
    public OrderInfoResponse getOrderInfoCut(OrderResponse orderResponse) {
        OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
        Orders orders = orderResponse.getOrders();
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        orderInfoResponse.setOrderNo(orders.getOrderNo());
        orderInfoResponse.setOrderInfoId(ordersInfo.getId());
        orderInfoResponse.setPayChannel(null);
        orderInfoResponse.setPayPhone(orders.getTel());
        orderInfoResponse.setCreateOrderTime(orders.getCreateTime());
        orderInfoResponse.setPayType(null);
        orderInfoResponse.setPayTime(orders.getPayTime());
        orderInfoResponse.setPayOrderNo(orders.getTradeNo());
        // 签收时间
        orderInfoResponse.setReceiveTime(ordersInfo.getReceiveTime());
        // 是否导出订单
        orderInfoResponse.setIsExportOrder(ordersInfo.getIsExport());
        return orderInfoResponse;
    }

    /**
     * 物流信息
     */
    public ExpressInfoResponse getExpressInfo(OrderResponse orderResponse) {
        Orders orders = orderResponse.getOrders();
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        ExpressInfoResponse expressInfoResponse = new ExpressInfoResponse();
        expressInfoResponse.setReceiveName(orders.getUserName());
        expressInfoResponse.setPhone(orders.getUserPhone());
        expressInfoResponse.setDeliveryAddress(orders.getUserAddress());
        expressInfoResponse.setChannel(orders.getChannel());
        expressInfoResponse.setExpressName(this.getExpressName(ordersInfo.getExpressCompanyNo()).getExpressKey());
        expressInfoResponse.setExpressNo(ordersInfo.getExpressNo());
        expressInfoResponse.setReceiveDate(ordersInfo.getReceiveTime());
        // 发货日期
        String expressNo = ordersInfo.getExpressNo();
        String expressCompanyNo = ordersInfo.getExpressCompanyNo();
        Date deliveryTime = null;
        if(!StringUtils.isEmpty(expressNo) && !StringUtils.isEmpty(expressCompanyNo)) {
            deliveryTime  = ordersDao.getDeliveryTime(expressCompanyNo, expressNo);
        }
        expressInfoResponse.setDeliveryDate(deliveryTime);
        return expressInfoResponse;
    }

    /**
     * 物流信息缩减版
     */
    public ExpressInfoResponse getExpressInfoCut(OrderResponse orderResponse) {
        Orders orders = orderResponse.getOrders();
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        ExpressInfoResponse expressInfoResponse = new ExpressInfoResponse();
        expressInfoResponse.setReceiveName(orders.getUserName());
        expressInfoResponse.setPhone(orders.getUserPhone());
        expressInfoResponse.setDeliveryAddress(orders.getUserAddress());
        expressInfoResponse.setChannel(null);
        expressInfoResponse.setExpressName(this.getExpressName(ordersInfo.getExpressCompanyNo()).getExpressKey());
        expressInfoResponse.setExpressNo(ordersInfo.getExpressNo());
        expressInfoResponse.setReceiveDate(ordersInfo.getReceiveTime());
        // 发货日期
        String expressNo = ordersInfo.getExpressNo();
        String expressCompanyNo = ordersInfo.getExpressCompanyNo();
        Date deliveryTime = null;
        if(!StringUtils.isEmpty(expressNo) && !StringUtils.isEmpty(expressCompanyNo)) {
            deliveryTime  = ordersDao.getDeliveryTime(expressCompanyNo, expressNo);
        }
        expressInfoResponse.setDeliveryDate(deliveryTime);
        return expressInfoResponse;
    }


    /**
     * 优惠信息
     */
    public OrderDiscountsResponse getOrderDiscounts(OrderResponse orderResponse, Product product,OrdersSpec productSpec) {
        Orders orders = orderResponse.getOrders();
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        OrderDiscountsResponse orderDiscountsResponse = new OrderDiscountsResponse();
        // 收益
        BigDecimal profit = orders.getRealTotalMoney().subtract(product.getCostPrice());
        if(product.getIsZeroProduct() == 1) {
            profit = BigDecimal.ZERO;
        }
        orderDiscountsResponse.setProductId(product.getId());
        orderDiscountsResponse.setProductName(product.getProductName());
        orderDiscountsResponse.setProductCostPrice(productSpec.getCostPrice());
        orderDiscountsResponse.setProductOriginalPrice(productSpec.getOriginalPrice());
        orderDiscountsResponse.setRealPayMoney(BigDecimal.ZERO);
        orderDiscountsResponse.setProductEarnings(BigDecimal.ZERO);
        if(orders.getIsPay() == 1) {
            orderDiscountsResponse.setRealPayMoney(orders.getRealTotalMoney());
            orderDiscountsResponse.setProductEarnings(profit);
        }
        String activityType = product.getActivityType();
        // 优惠券减免
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_COUPON.name())) {
            orderDiscountsResponse.setCashCoupon(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "元");
        }
        // 积分抵扣
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_SCORE.name())) {
            orderDiscountsResponse.setScoreDeduction(product.getOriginalPrice().subtract(product.getPrice()) + "");
        }
        // 红包抵扣
        orderDiscountsResponse.setRedEnvelopeDeduction(String.valueOf(orders.getDeductionMoney()));
        // 商品佣金
        return orderDiscountsResponse;
    }

    /**
     * 优惠信息缩减版
     */
    public OrderDiscountsResponse getOrderDiscountsCut(OrderResponse orderResponse, Product product,OrdersSpec productSpec) {
        Orders orders = orderResponse.getOrders();
        OrdersInfo ordersInfo = orderResponse.getOrdersInfoList().get(0);
        OrderDiscountsResponse orderDiscountsResponse = new OrderDiscountsResponse();
        // 收益
        BigDecimal profit = orders.getRealTotalMoney().subtract(product.getCostPrice());
        if(product.getIsZeroProduct() == 1) {
            profit = BigDecimal.ZERO;
        }
        orderDiscountsResponse.setProductId(product.getId());
        orderDiscountsResponse.setProductName(product.getProductName());
        orderDiscountsResponse.setProductCostPrice(null);
        orderDiscountsResponse.setProductOriginalPrice(null == productSpec? null : productSpec.getOriginalPrice());
        orderDiscountsResponse.setRealPayMoney(BigDecimal.ZERO);
        orderDiscountsResponse.setProductEarnings(BigDecimal.ZERO);
        if(orders.getIsPay() == 1) {
            orderDiscountsResponse.setRealPayMoney(orders.getRealTotalMoney());
            orderDiscountsResponse.setProductEarnings(profit);
        }
        // 优惠券减免
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_COUPON.name())) {
            orderDiscountsResponse.setCashCoupon(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "元");
        }
        // 积分抵扣
        if(product.getActivityType().equals(ActivityTypeEnums.CASH_SCORE.name())) {
            orderDiscountsResponse.setScoreDeduction(product.getOriginalPrice().subtract(product.getPrice()) + "");
        }
        // 红包抵扣
        orderDiscountsResponse.setRedEnvelopeDeduction(null == orders.getDeductionMoney() ? "0" : String.valueOf(orders.getDeductionMoney()));
        // 商品佣金
        return orderDiscountsResponse;
    }

    /**
     * 根据快递编码获取快递名称
     * @return
     */
    public ExpressDic getExpressName(String expressCode) {
        return expressDao.getExpressName(expressCode);
    }

    @Override
    public MainOrderResponse getOrderDetailByOrderNo(String orderNo) {

        MainOrderResponse mainOrderResponse = new MainOrderResponse();

        mainOrderResponse.setOrderNo(orderNo);

        //根据订单号查主订单
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andOrderNoEqualTo(orderNo);
        Orders orders = ordersDao.selectByOrderNo(orderNo);
        if (null == orders){
            throw new ApiException("订单信息异常");
        }
        mainOrderResponse.setSmallNote(orders.getSmallNote());

        //根据主订单号查订单详情
        List<OrdersInfo> orderInfoList = ordersDao.selectOrderInfoList(orders.getId(),null,null);

        OrdersPayExample ordersPayExample = new OrdersPayExample();
        ordersPayExample.createCriteria().andOrderNoEqualTo(orderNo).andPayTypeEqualTo(PayPayTypeEnums.SUCCEED.getType());
        List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(ordersPayExample);

        //订单信息
        OrderMessageResp orderMessageResp = new OrderMessageResp();
        orderMessageResp.setUserId(orders.getUserId());
        orderMessageResp.setTel(orders.getTel());
        orderMessageResp.setOrderSource(orders.getOrderSource());
        orderMessageResp.setCreateTime(orders.getCreateTime());
        mainOrderResponse.setOrderMessageResp(orderMessageResp);

        //支付信息
        PayMessageResp payMessageResp = new PayMessageResp();
        payMessageResp.setPaySource(orders.getPaySource());
        payMessageResp.setPayTime(orders.getPayTime());
        payMessageResp.setPayType(orders.getPayType());
        payMessageResp.setResOrderNo(!CollectionUtils.isEmpty(ordersPays) ? ordersPays.get(0).getResOrderNo() : null);
        payMessageResp.setPurseDeduction(orders.getDeductionMoney());
        mainOrderResponse.setPayMessageResp(payMessageResp);

        //收货信息
        ReceiveMessageResp receiveMessageResp = new ReceiveMessageResp();
        if (null != orders.getRealNameId()) {
            UsersRealName usersRealName = usersRealNameMapper.selectByPrimaryKey(orders.getRealNameId());
            receiveMessageResp.setOrderName(usersRealName.getName());
            receiveMessageResp.setOrderCard(usersRealName.getCard());
        }

        receiveMessageResp.setUserName(orders.getUserName());
        receiveMessageResp.setUserPhone(orders.getUserPhone());
        receiveMessageResp.setUserAddress(orders.getUserAddress());
        receiveMessageResp.setOrderRemarks(orders.getOrderRemarks());
        mainOrderResponse.setReceiveMessageResp(receiveMessageResp);

        //商品信息
        List<ProductMessageResp> productMessageResps = new ArrayList<>();

        final BigDecimal[] count = {new BigDecimal(0)};

        final BigDecimal[] actualPaymentMoney = {BigDecimal.ZERO};

        List<Integer> bankerIdList = orderInfoList.stream().filter(item -> null != item.getBankerId()).map(OrdersInfo::getBankerId).collect(Collectors.toList());
        BankerRequest bankerRequest = new BankerRequest();
        bankerRequest.setBankerIdList(bankerIdList);
        String json = JSON.toJSONString(bankerRequest);
        String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/product/getBankerMsg", json, supplyApiConfig.getHeadsMap());
        List<BankerResponse> bankerResponses = JSONObject.parseArray(result, BankerResponse.class);


        orderInfoList.forEach(item ->{
            List<BankerResponse> collect = bankerResponses.stream().filter(response -> response.getBankerId().equals(item.getBankerId())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)){
                item.setBankerName(collect.get(0).getBankerName());
            }

            ProductMessageResp productMessageResp = new ProductMessageResp();
            productMessageResp.setChildOrderNo(item.getChildOrderNo());
            productMessageResp.setOrderInfoStatus(Integer.valueOf(item.getOrderinfoStatus()));
            productMessageResp.setProductId(item.getProductId());
            productMessageResp.setBankerName(item.getBankerName());
            productMessageResp.setProductName(item.getProductName());
            productMessageResp.setProductSkuSpec(item.getProductSkuSpec());
            productMessageResp.setProductSum(item.getProductSum());
            productMessageResp.setCostPrice(item.getCostPrice());
            productMessageResp.setProductPrice(item.getProductPrice());
            productMessageResp.setPayPrice(item.getPayPrice());
            productMessageResp.setOrderInfoId(item.getId());
            productMessageResp.setProductOprice(item.getProductOprice());
            productMessageResp.setProductDiscounts(item.getProductOprice().subtract(item.getProductPrice()));
            productMessageResp.setDiscountMessage(ActivityEnums.getActivityType(item.getActivityType()));
            productMessageResp.setProductImg(item.getProductImg());
            productMessageResp.setTotalMoney(orders.getTotalMoney());
            productMessageResp.setRealTotalMoney(orders.getIsPay() == 0 ? null : (orders.getRealTotalMoney().add(null != orders.getDeductionMoney() ? orders.getDeductionMoney() : BigDecimal.valueOf(0))));
            productMessageResp.setDeductionMoney(orders.getIsPay() == 0 ? null : orders.getDeductionMoney());
            productMessageResp.setFreight(item.getFreight());
            OrderDiscountsResponse orderDiscountsResponse = new OrderDiscountsResponse();

            actualPaymentMoney[0] = actualPaymentMoney[0].add(null != productMessageResp.getRealTotalMoney() ? productMessageResp.getRealTotalMoney() : BigDecimal.valueOf(0));

            count[0] = count[0].add(item.getProductPrice());

            String activityType = item.getActivityType();
            // 优惠券减免
            if(activityType.equals(ActivityTypeEnums.CASH_COUPON.name())) {
                orderDiscountsResponse.setCashCoupon(item.getActivityMax().stripTrailingZeros().toPlainString() + "元");
            }
            // 积分抵扣
            if(activityType.equals(ActivityTypeEnums.CASH_SCORE.name())) {
                orderDiscountsResponse.setScoreDeduction(item.getProductOprice().subtract(item.getProductPrice()) + "");
            }
            // 红包抵扣
            orderDiscountsResponse.setRedEnvelopeDeduction(String.valueOf(orders.getDeductionMoney()));
            productMessageResp.setOrderDiscountsList(orderDiscountsResponse);
            productMessageResps.add(productMessageResp);
        });
        mainOrderResponse.setProductMessageResp(productMessageResps);
        mainOrderResponse.setPriceSum(count[0]);
        mainOrderResponse.setRealTotalMoney(orders.getIsPay() == 0 ? null : actualPaymentMoney[0]);

        return mainOrderResponse;
    }

    @Override
    public Integer updateSmallNote(String orderNo, String smallNote) {
        return ordersDao.updateSmallNote(orderNo, smallNote);
    }

    @Override
    public List<SonOrderVO> selectOrderInfoAll(SonOrderDto sonOrderDto) {
        PageHelper.startPage(sonOrderDto.getPageNum(), sonOrderDto.getPageSize());
        return ordersDao.selectOrderInfoAll(sonOrderDto);
    }

    @Override
    public MainOrderResponse getChildOrderDetail(String orderNo,String childOrderNo,Integer orderInfoId) {
        MainOrderResponse mainOrderResponse = new MainOrderResponse();

        mainOrderResponse.setOrderNo(orderNo);

        //根据订单号查主订单
        Orders orders = ordersDao.selectByOrderNo(orderNo);
        if (null == orders){
            throw new ApiException("订单信息异常");
        }

        mainOrderResponse.setSmallNote(orders.getSmallNote());
        mainOrderResponse.setOrderId(orders.getId());
        mainOrderResponse.setOrdersResponse(orders);

        mainOrderResponse.setChildOrderNo(childOrderNo);
        OrdersPayExample ordersPayExample = new OrdersPayExample();
        ordersPayExample.createCriteria().andOrderNoEqualTo(orderNo).andPayTypeEqualTo(PayPayTypeEnums.SUCCEED.getType());
        List<OrdersPay> ordersPays = ordersPayMapper.selectByExample(ordersPayExample);

        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(orderInfoId);
        if (null == ordersInfo){
            throw new ApiException("订单信息异常");
        }
        mainOrderResponse.setOrderInfoStatus(Integer.valueOf(ordersInfo.getOrderinfoStatus()));
        mainOrderResponse.setServiceRemark(ordersInfo.getServiceRemark());

        // 根据订单详情id查订单备注
        List<OrderNote> orderNoteByInfoId = orderNoteDao.findOrderNoteByInfoId(orderInfoId);
        if (CollectionUtils.isEmpty(orderNoteByInfoId)) {
            mainOrderResponse.setSmallNote(null);
        } else {
            mainOrderResponse.setSmallNote(orderNoteByInfoId.get(0).getContent());
        }

        // 根据子订单号获取订单状态
        OrderStatusResponse orderStatusResponse = ordersDao.returnOrderStatus(ordersInfo.getId());
        orderStatusResponse.setStatus(OrderStatusConstant.CREATE_ORDER);
        // 判断是否付款 改变状态为 2
        if (orderStatusResponse.getIsPay() == 1) {
            orderStatusResponse.setStatus(OrderStatusConstant.PAY);
        }
        // 判断是否发货 改变状态为 3
        if (!StringUtils.isEmpty(orderStatusResponse.getExpressNo())) {
            orderStatusResponse.setStatus(OrderStatusConstant.DELIVERY);
        }
        // 判断是否接收 改变状态为 5
        if (orderStatusResponse.getReceiveTime() != null) {
            orderStatusResponse.setStatus(OrderStatusConstant.INVALID);
        }
        mainOrderResponse.setOrderStatusResponse(orderStatusResponse);
        mainOrderResponse.setOrdersInfoId(orderStatusResponse.getId());

        UsersRealName usersRealName = new UsersRealName();
        if (null != orders.getRealNameId()) {
            usersRealName = usersRealNameMapper.selectByPrimaryKey(orders.getRealNameId());
        }

        MainOrderResponse message = getMessage(mainOrderResponse, orders, ordersPays, usersRealName);

        ExpressMessageResp expressMessageResp = new ExpressMessageResp();
        ExpressDic expressName = expressDao.getExpressName(ordersInfo.getExpressCompanyNo());
        if (null != expressName){
            expressMessageResp.setExpressName(expressName.getExpressKey());
            expressMessageResp.setExpressCompany(expressName.getExpressValue());
        }
        expressMessageResp.setDeliveryTime(ordersInfo.getDeliveryTime());
        expressMessageResp.setExpressNo(ordersInfo.getExpressNo());
        message.setExpressMessageResp(expressMessageResp);

        //商品信息
        List<ProductMessageResp> productMessageResps = new ArrayList<>();
        ProductMessageResp productMessageResp = new ProductMessageResp();
        productMessageResp.setChildOrderNo(ordersInfo.getChildOrderNo());
        productMessageResp.setOrderInfoStatus(Integer.valueOf(ordersInfo.getOrderinfoStatus()));
        //查询供应商名称
        List<Integer> bankerIdList = new ArrayList<>();
        bankerIdList.add(ordersInfo.getBankerId());
        BankerRequest bankerRequest = new BankerRequest();
        bankerRequest.setBankerIdList(bankerIdList);
        String json = JSON.toJSONString(bankerRequest);
        String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/product/getBankerMsg", json, supplyApiConfig.getHeadsMap());
        List<BankerResponse> bankerResponses = JSONObject.parseArray(result, BankerResponse.class);
        if (!CollectionUtils.isEmpty(bankerResponses)){
            BankerResponse bankerResponse = bankerResponses.get(0);
            productMessageResp.setBankerName(bankerResponse.getBankerName());
        }
        productMessageResp.setProductId(ordersInfo.getProductId());
        productMessageResp.setProductName(ordersInfo.getProductName());
        productMessageResp.setProductImg(ordersInfo.getProductImg());
        productMessageResp.setDescr(ordersInfo.getDescr());
        productMessageResp.setProductSkuSpec(ordersInfo.getProductSkuSpec());
        productMessageResp.setProductSum(ordersInfo.getProductSum());
        productMessageResp.setCostPrice(ordersInfo.getCostPrice());
        productMessageResp.setProductPrice(ordersInfo.getProductPrice());
        // 商品价格 - 钱包抵扣 - 优惠价格 = 实际支付金额  暂时不做优惠
        BigDecimal payPrice = ordersInfo.getProductPrice();
        productMessageResp.setPayPrice(orders.getIsPay() == 0 ? null : payPrice);
        productMessageResp.setProductOprice(ordersInfo.getProductOprice());
        productMessageResp.setProductDiscounts(ordersInfo.getProductOprice().subtract(ordersInfo.getProductPrice()));
        productMessageResp.setDiscountMessage(ActivityEnums.getActivityType(ordersInfo.getActivityType()));

        OrdersInfoFreightExample ordersInfoFreightExample = new OrdersInfoFreightExample();
        ordersInfoFreightExample.createCriteria().andChildOrderNoEqualTo(ordersInfo.getChildOrderNo());
        List<OrdersInfoFreight> ordersInfoFreights = ordersInfoFreightMapper.selectByExample(ordersInfoFreightExample);
        if (!CollectionUtils.isEmpty(ordersInfoFreights)) {
            productMessageResp.setFreight(ordersInfoFreights.get(0).getFreight());
        }
        productMessageResp.setRealTotalMoney(orders.getIsPay() == 0 ? BigDecimal.valueOf(0) : (ordersInfo.getProductPrice().add(null != productMessageResp.getFreight() ? productMessageResp.getFreight() : BigDecimal.valueOf(0))));

        OrderDiscountsResponse orderDiscountsResponse = new OrderDiscountsResponse();

        String activityType = ordersInfo.getActivityType();

        // 优惠券减免
        if (activityType.equals(ActivityTypeEnums.CASH_COUPON.name())) {
            orderDiscountsResponse.setCashCoupon(ordersInfo.getActivityMax().stripTrailingZeros().toPlainString() + "元");
        }
        // 积分抵扣
        if (activityType.equals(ActivityTypeEnums.CASH_SCORE.name())) {
            orderDiscountsResponse.setScoreDeduction(ordersInfo.getProductOprice().subtract(ordersInfo.getProductPrice()) + "");
        }
        // 红包抵扣
        orderDiscountsResponse.setRedEnvelopeDeduction(String.valueOf(orders.getDeductionMoney()));
        productMessageResp.setOrderDiscountsList(orderDiscountsResponse);
        productMessageResps.add(productMessageResp);

        if (ordersInfo.getOrderinfoStatus().equals("0") || orderStatusResponse.getIsPay() == 0) {
            message.setProcessStatus(1);
        }else if (ordersInfo.getOrderinfoStatus().equals("1")) {
            message.setProcessStatus(2);
        }else if (ordersInfo.getOrderinfoStatus().equals("2")) {
            message.setProcessStatus(3);
        }else if (ordersInfo.getOrderinfoStatus().equals("3")) {
            message.setProcessStatus(5);
        }else {
            message.setProcessStatus(5);
        }
        message.setProductMessageResp(productMessageResps);
        return message;

    }

    /**
     *  获取订单信息\支付信息\收货信息
     * @param mainOrderResponse
     * @param orders
     * @param ordersPays
     * @return
     */
    public MainOrderResponse getMessage(MainOrderResponse mainOrderResponse, Orders orders, List<OrdersPay> ordersPays, UsersRealName usersRealName) {
        //订单信息
        OrderMessageResp orderMessageResp = new OrderMessageResp();
        orderMessageResp.setUserId(orders.getUserId());
        orderMessageResp.setTel(orders.getTel());
        orderMessageResp.setOrderSource(orders.getOrderSource());
        orderMessageResp.setCreateTime(orders.getCreateTime());
        mainOrderResponse.setOrderMessageResp(orderMessageResp);

        //支付信息
        PayMessageResp payMessageResp = new PayMessageResp();
        payMessageResp.setPaySource(orders.getPaySource());
        payMessageResp.setPayTime(orders.getPayTime());
        payMessageResp.setPayType(orders.getPayType());
        payMessageResp.setResOrderNo(orders.getTradeNo());
        mainOrderResponse.setPayMessageResp(payMessageResp);

        //收货信息
        ReceiveMessageResp receiveMessageResp = new ReceiveMessageResp();

        receiveMessageResp.setProvince(orders.getProvince());
        receiveMessageResp.setCity(orders.getCity());
        receiveMessageResp.setArea(orders.getArea());
        receiveMessageResp.setAddress(orders.getAddress());
        receiveMessageResp.setUserName(orders.getUserName());
        receiveMessageResp.setUserPhone(orders.getUserPhone());
        receiveMessageResp.setUserAddress(orders.getUserAddress());
        receiveMessageResp.setOrderRemarks(orders.getOrderRemarks());
        receiveMessageResp.setOrderCard(usersRealName.getCard());
        receiveMessageResp.setOrderName(usersRealName.getName());
        mainOrderResponse.setReceiveMessageResp(receiveMessageResp);
        return mainOrderResponse;
    }

    /**
     * 修改子订单状态为已发货
     * @param orderInfoId
     * @return
     */
    @Override
    public CommonResult updateOrderInfoStatus(Integer orderInfoId) {
        //根据子订单号查询子订单
        OrdersInfo ordersInfo = ordersDao.selectByChildOrderNo(orderInfoId);
        if (null == ordersInfo){
            throw new ApiException("订单信息异常");
        }
        //判断子订单是否为未发货
        //修改子订单为已发货
        ordersInfo.setOrderinfoStatus("2");
        int i = ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);

        //根据主订单号查询关联这个主订单id的全部子订单
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andOrderIdEqualTo(ordersInfo.getOrderId());
        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);

        Orders orders = ordersMapper.selectByPrimaryKey(ordersInfo.getOrderId());

        if (orders.getOrderStatus().equals("1")){
            List<String> list = new ArrayList<>();
            ordersInfos.stream().forEach(item ->{
                list.add(item.getOrderinfoStatus());
            });
            if (!list.contains("1")){
                orders.setOrderStatus("2");
                ordersMapper.updateByPrimaryKey(orders);
            }
        }
        if (i > 0){
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @Override
    public CommonResult updateAddress(ReceiveAddressRequest request) {
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria().andOrderNoEqualTo(request.getOrderNo());
        List<Orders> ordersList = ordersMapper.selectByExample(ordersExample);
        if (CollectionUtils.isEmpty(ordersList)) {
            throw new ApiException("订单信息异常,修改失败");
        }
        Orders orders = ordersList.get(0);
        //订单为待发货才能修改收货地址
        if ("1".equals(orders.getOrderStatus())){
            orders.setUserName(request.getUserName());
            orders.setUserPhone(request.getUserPhone());
            orders.setProvince(request.getProvince());
            orders.setCity(request.getCity());
            orders.setArea(request.getArea());
            orders.setAddress(request.getAddress());
            String userAddress = request.getProvince() + (StringUtils.isEmpty(request.getCity()) ? "" : request.getCity()) + (StringUtils.isEmpty(request.getArea()) ? "" : request.getArea()) + request.getAddress();
            orders.setUserAddress(userAddress);
            int i = ordersMapper.updateByPrimaryKeySelective(orders);

            //调用供应链接口修改订单收货地址
            if (i > 0) {
                try {
                    String json = JSON.toJSONString(request);
                    HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/updateAddress", json, supplyApiConfig.getHeadsMap());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return CommonResult.success("修改收货人信息成功");
        }
        return CommonResult.failed("修改收货人信息失败");
    }

    @Override
    public boolean insertOrderRemark(String childOrderNo,String serviceRemark, Integer orderInfoId) {
        if (StringUtil.isEmpty(childOrderNo)){
            return false;
        }
        OrdersInfo ordersInfo = new OrdersInfo();
        ordersInfo.setId(orderInfoId);
        ordersInfo.setServiceRemark(serviceRemark);
        boolean remark = ordersDao.updateServiceRemark(ordersInfo);
        if (remark == true) {
            BankerOrder bankerOrder = new BankerOrder();
            bankerOrder.setOrderNo("QMYX" + orderInfoId);
            bankerOrder.setSmallNote(serviceRemark);
            ordersMapper.updateBankerOrderAddress(bankerOrder);
        }
        return remark;
    }

    @Override
    public List<OrdersExportResponse> findAllOrderInfo(OrdersInfoRequest ordersInfoRequest) {
        PageHelper.startPage(ordersInfoRequest.getPageNum(), ordersInfoRequest.getPageSize());
        List<OrdersExportResponse> orderInfo = ordersDao.findAllOrderInfo(ordersInfoRequest);
        if (!CollectionUtils.isEmpty(orderInfo)) {

            List<String> childOrderNoList = orderInfo.stream().filter(item -> null != item.getChildOrderNo()).map(OrdersExportResponse::getChildOrderNo).collect(Collectors.toList());

            List<String> orderNoList = orderInfo.stream().filter(item -> null != item.getOrderNo()).map(OrdersExportResponse::getOrderNo).collect(Collectors.toList());
            //运费
            List<OrdersInfoFreightDto> ordersInfoFreightDtoList = ordersDao.selectFreightByChildOrderNoList(childOrderNoList);
            //支付信息
            OrdersPayExample ordersPayExample = new OrdersPayExample();
            ordersPayExample.createCriteria().andOrderNoIn(orderNoList).andPayTypeEqualTo(PayPayTypeEnums.SUCCEED.getType());
            List<OrdersPay> ordersPayList = ordersPayMapper.selectByExample(ordersPayExample);
            //售后信息
            List<Integer> orderInfoIds = orderInfo.stream().map(OrdersExportResponse::getId).collect(Collectors.toList());
            List<ReturnGoods> returnGoodsList = returnGoodsDao.getListByOrderInfoIds(orderInfoIds);

            //实名认证
//            List<UsersRealName> usersRealNames = new ArrayList<>();
//            Set<Integer> realNameIds = orderInfo.stream().filter(item -> null != item.getRealNameId()).map(OrdersExportResponse::getRealNameId).collect(Collectors.toSet());
//            if (!CollectionUtils.isEmpty(realNameIds)){
//                List<Integer> realNameIdLists = new ArrayList<>(realNameIds);
//                usersRealNames = usersRealNameMapper.selectByIds(realNameIdLists);
//            }
            //是否限制展示供货价角色
            boolean isLimitRole = channelProductService.checkIsLimitRole();

//            List<UsersRealName> finalUsersRealNames = usersRealNames;
            orderInfo.stream().forEach(item -> {

                //供货价
                item.setSupplyPrice(item.getCostPrice());
                if (isLimitRole) {
                    item.setSupplyPrice(BigDecimal.ZERO);
                }

                //实名认证信息
//                if (!CollectionUtils.isEmpty(finalUsersRealNames)) {
//                    List<UsersRealName> usersRealNameList = finalUsersRealNames.stream().filter(usersRealName -> usersRealName.getId().equals(item.getRealNameId())).collect(Collectors.toList());
//                    if (!CollectionUtils.isEmpty(usersRealNameList)) {
//                        item.setAuthenticatedCard(usersRealNameList.get(0).getCard());
//                        item.setAuthenticatedName(usersRealNameList.get(0).getName());
//                    }
//                }
                //运费
                if (!CollectionUtils.isEmpty(ordersInfoFreightDtoList)) {
                    List<OrdersInfoFreightDto> ordersInfoFreightDtos = ordersInfoFreightDtoList.stream().filter(ordersInfoFreightDto -> ordersInfoFreightDto.getChildOrderNo().equals(item.getChildOrderNo())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(ordersInfoFreightDtos)) {
                        item.setFreight(ordersInfoFreightDtos.get(0).getFreight());
                    }
                }
                //支付订单号
//                if (!CollectionUtils.isEmpty(ordersPayList)) {
//                    List<OrdersPay> payList = ordersPayList.stream().filter(ordersPay -> ordersPay.getOrderNo().equals(item.getOrderNo())).collect(Collectors.toList());
//                    if (!CollectionUtils.isEmpty(payList)) {
//                        item.setResOrderNo(payList.get(0).getResOrderNo());
//                        item.setAliPayJsApiFlag(payList.get(0).getTradeType().equals("aliPay-jsApi") ? "是":"不是");
//                        item.setChildId(payList.get(0).getChildId());
//                        if ("aliPay-jsApi".equals(payList.get(0).getTradeType()) || "aliPay".equals(payList.get(0).getTradeType())) {
//                            item.setAliPayAccount("qmkj4089@163.com");
//                        }
//                    }
//                }
                //售后信息
                if (!CollectionUtils.isEmpty(returnGoodsList)) {
                    List<ReturnGoods> collect = returnGoodsList.stream().filter(item2 -> item2.getOrdersInfoId().equals(item.getId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        List<ReturnGoods> collect2 = collect.stream().sorted(Comparator.comparing(ReturnGoods::getId).reversed()).collect(Collectors.toList());
                        item.setServiceNo(collect2.get(0).getServiceNo());
                        item.setAmount(collect2.get(0).getAmount());
                        item.setReturnGoodStatus(collect2.get(0).getStatus());
                    }
                }

                item.setPaySource(Optional.ofNullable(PayTypeEnums.getPayType(item.getPaySource())).orElse(""));
                String expressCode = ExpressNameCode.getExpressName(item.getExpressCompanyNo());
                item.setExpressCompanyNo(expressCode);
                BigDecimal totalMoney =  item.getPrice() == null ? BigDecimal.ZERO :  item.getPrice().add( Optional.ofNullable(item.getFreight()).orElse(BigDecimal.ZERO));
                item.setTotalMoney(totalMoney);
                item.setAddress(item.getProvince() + item.getCity() +item.getArea() );
            });
        }
        return orderInfo;
    }

    @Override
    public String exportOrderInfo(OrdersInfoRequest ordersInfoRequest) throws Exception{

        //查询要导出的数据，第一页查1000条
        Date date = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowDate = sbf.format(date);
        String fileName;
        String fileUrl = null;
        OutputStream outputStream =null;
        try {
            fileName =  "子订单-"+nowDate + ".xlsx";
            outputStream =new FileOutputStream(path+fileName);;
            fileUrl =    fileName;
            Integer totalCount = ordersDao.findAllOrderInfoCount(ordersInfoRequest);
            if (totalCount <= 0) {
                throw new ApiException("查询数据为空，导出失败");
            }

            //每一个Sheet存放100w条数据
            Integer sheetDataRows = PER_SHEET_ROW_COUNT;
            //每次写入的数据量20w,每页查询20W
            Integer writeDataRows = PER_WRITE_ROW_COUNT;
            //计算需要的Sheet数量
            Integer sheetNum = totalCount % sheetDataRows == 0 ? (totalCount / sheetDataRows) : (totalCount / sheetDataRows + 1);
            //计算一般情况下每一个Sheet需要写入的次数(一般情况不包含最后一个sheet,因为最后一个sheet不确定会写入多少条数据)
            Integer oneSheetWriteCount = sheetDataRows / writeDataRows;
            //计算最后一个sheet需要写入的次数
            Integer lastSheetWriteCount = totalCount % sheetDataRows == 0 ? oneSheetWriteCount : (totalCount % sheetDataRows % writeDataRows == 0 ? (totalCount / sheetDataRows / writeDataRows) : (totalCount / sheetDataRows / writeDataRows + 1));
            if(totalCount >= writeDataRows && totalCount< sheetDataRows ) {
                lastSheetWriteCount = totalCount % writeDataRows == 0 ? totalCount/writeDataRows : totalCount/writeDataRows +1;
            }
            //必须放到循环外，否则会刷新流
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            //开始分批查询分次写入
            for (int i = 0; i < sheetNum; i++) {
                //创建Sheet
                WriteSheet sheet = new WriteSheet();
                sheet.setSheetName("Sheet"+i);
                sheet.setSheetNo(i);
                //循环写入次数: j的自增条件是当不是最后一个Sheet的时候写入次数为正常的每个Sheet写入的次数,如果是最后一个就需要使用计算的次数lastSheetWriteCount
                for (int j = 0; j < (i != sheetNum - 1 ? oneSheetWriteCount : lastSheetWriteCount); j++) {
                    //分页查询一次20w
                    Page page1 = new Page(j +1 + oneSheetWriteCount * i, writeDataRows);
                    //查询分页列表---按照自己的业务查列表，分页这个一定要使用这个：page1.getPageNum(),page1.getPageSize()！！！
                    ordersInfoRequest.setPageNum(page1.getPageNum());
                    ordersInfoRequest.setPageSize(page1.getPageSize());
                    log.info("查询导出参数:{}",JSONObject.toJSON(ordersInfoRequest));
                    List<OrdersExportResponse> allOrderInfo = findAllOrderInfo(ordersInfoRequest);
                    log.info("查询导出返回条数data:{}",allOrderInfo.size());
                    List<OrdersInfoExportResponse> data = new ArrayList<>();
                    allOrderInfo.stream().forEach(ordersResponse -> {
                        OrdersInfoExportResponse response = new OrdersInfoExportResponse();
                        BeanUtils.copyProperties(ordersResponse,response);
                        response.setIsPay(ordersResponse.getIsPay() == null ? "" : ordersResponse.getIsPay()== 1 ? "已支付":"未支付" );
                        response.setOrdersInfoStatus(OrderStatusEnums.getStatusDesc(ordersResponse.getOrderStatus()));
                        response.setPayType(ordersResponse.getPayType() == null ? "" : OrderPayTypeEnum.getName(ordersResponse.getPayType()));
                        response.setIsZeroProduct(ordersResponse.getIsZeroProduct() == null ? "" :ordersResponse.getIsZeroProduct()==1 ? "是" : "不是");
                        response.setReturnGoodStatus(ordersResponse.getReturnGoodStatus() == null ? "" : ReturnGoodsStatusEnums.getMessageByCode(ordersResponse.getReturnGoodStatus()));
                        response.setPayNo(ordersResponse.getResOrderNo());
                        data.add(response);
                    });

                    log.info("查询导出返回条数data:{}",data.size());
                    WriteSheet writeSheet = EasyExcel.writerSheet(i, "Sheet" + (i + 1)).head(OrdersInfoExportResponse.class)
                            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                    excelWriter.write(data, writeSheet);

                }
            }
            excelWriter.finish();
            outputStream.flush();
            outputStream.close();

            // 初始化OssClient
            OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
            File file = new File(path+fileName);
            FileInputStream fileInputStream = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
            FileResponse fileResponse = AliyunOSSClientUtil.uploadObject2OSS(ossClient, multipartFile, "orderInfo");
            // 插入导出记录
            ExportRecord exportRecord = new ExportRecord();
            exportRecord.setFileName(fileName);
            exportRecord.setFileUrl(fileResponse.getUrl());
            exportRecord.setCreateTime(new Date());
            exportRecord.setExportType(2);
            exportRecord.setAdminId(ordersInfoRequest.getAdminId());
            exportRecordMapper.insert(exportRecord);
        } catch (Exception e) {
            log.error("导出错误：{}",e.getMessage());
        }finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        return fileUrl;
    }

    @Override
    public CommonPage getExportOrderInfoRecordList(QueryOrderRecordRequest queryOrderRecordRequest) {
        PageHelper.startPage(queryOrderRecordRequest.getPageNum(), queryOrderRecordRequest.getPageSize());
        ExportRecordExample exportRecordExample = new ExportRecordExample();
        exportRecordExample.createCriteria().andExportTypeEqualTo(2).andAdminIdEqualTo(queryOrderRecordRequest.getAdminId());
        exportRecordExample.setOrderByClause("id desc");
        List<ExportRecord> exportRecords = exportRecordMapper.selectByExample(exportRecordExample);
        CommonPage commonPage = CommonPage.restPage(exportRecords);
        return commonPage;
    }

    @Override
    public int batchUpdateChildOrderStatus(NotifyOrderInfoRequest request) {
        return ordersDao.batchUpdateChildOrderStatus(request);
    }

    @Override
    public void updateOrderStatus(NotifyOrderInfoRequest request) {
        List<Orders> ordersList = ordersDao.findOrderIdsByChild(request);
        for (Orders order:ordersList){
            Integer newStatus = Integer.parseInt(request.getStatus());
            Integer oldStatus = Integer.parseInt(order.getOrderStatus());
            if (newStatus>oldStatus){
                ordersMapper.updateOrderStatus(order.getId(),newStatus);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrdersExpressInfo(List<NewImportOrderRequest> ordersExpressRequestList) {
        List<NewImportOrderRequest> list = ordersExpressRequestList.stream()
                .map(item -> {
                    item.setUpdateTime(new Date());
                    item.setExpressCode(ExpressDicUtil.getValue(item.getExpressCode().trim()));
                    return item;
                }).collect(Collectors.toList());
        try {
            // 更新分发系统数据库
//            bankerOrderMapper.updateBankerOrders(list);
            ordersDao.updateBankerOrders(list);
        } catch (Exception e) {
            log.error(" 失败异常信息 :{}", GlobalExceptionHandler.getExceptionToString(e));
            throw new ApiException("导入失败，请核对表格重试！");
        }
    }

    @Override
    public int updateOrderExpressBySaleSystem(String childOrderNo, String expressCompanyCode, String expressNo) {
        return ordersDao.updateExpressByChildOrderNo(childOrderNo, expressCompanyCode, expressNo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer adapayCallBack(HttpServletRequest request){
        boolean b = adaPayService.checkSign(request);
        Integer error = 500;
        Integer success = 200;
        if (b) {
            String data = request.getParameter("data");
            if (null != data) {
                Map<String, String> sMap = JSONObject.parseObject(data, Map.class);
                String status = sMap.get("status");
                //退款成功
                if ("succeeded".equals(status)) {
                    String tradeNo = sMap.get("refund_order_no");
                    OrdersExample ordersExample = new OrdersExample();
                    ordersExample.createCriteria().andTradeNoEqualTo(tradeNo);
                    List<Orders> orders = ordersMapper.selectByExample(ordersExample);
                    if(CollectionUtils.isEmpty(orders)){
                        log.error("===={Adapay回调退款,支付订单：{}不存在=====",tradeNo);
                    }
                    else if(1 == orders.get(0).getIsRefund()){
                        log.error("===={Adapay回调退款,支付订单：{}已退款=====",tradeNo);
                    } else if (0 == orders.get(0).getIsRefund()) {
                        Orders order = orders.get(0);
                        Integer id = order.getId();
                        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectOrderInfoByOrderId(id);
                        //当前只支持一笔子订单
                        OrdersInfo ordersInfo = ordersInfos.get(0);
                        // 查询退货单
                        ReturnGoods returnGoods = returnGoodsDao.selectReturnGoodsByWaitBackAmount(ordersInfo.getId());
                        //获取原路返回数据信息
                        ReturnRegister register = returnRegisterDao.getReturnRegisterByOid(ordersInfo.getId());
                        OrdersRefundExample example = new OrdersRefundExample();
                        example.createCriteria().andOrdersInfoIdEqualTo(ordersInfo.getId());
                        List<OrdersRefund> refundList = refundMapper.selectByExample(example);
                        OrdersRefund ordersRefund = new OrdersRefund();
                        if (CollectionUtils.isEmpty(refundList)) {
                            return error;
                        }
                        ordersRefund = refundList.get(0);
                        returnRegisterService.updateAdminOrderInfo(order, ordersRefund, ordersInfo, register, returnGoods);
                        //更新供应链订单状态 * 销售端调用 （当销售端退款后，需要修改订单状态）
                        returnRegisterService.querySupplyChainOrderInfo(ordersInfo.getChildOrderNo(), returnGoods.getServiceNo());
                        return success;
                    }
                } else {
                    log.error("Adapay回调退款失败！{}",JSON.toJSONString(data));
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
            }
        } else {
            log.info("Adapay支付验签失败！");
        }
        return error;
    }

    @Override
    public OrdersInfo queryByChildOrderNo(String childOrderNo) {
        OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
        ordersInfoExample.createCriteria().andChildOrderNoEqualTo(childOrderNo);
        List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
        if (CollectionUtils.isEmpty(ordersInfos)) {
            return null;
        }
        return ordersInfos.get(0);
    }

    @Override
    public void downloadExcel(String fileName, HttpServletResponse response) {
        //文件在服务器的路径
        String serverPath = path + fileName;
        InputStream inputStream = null;
        OutputStream out = null;
        try {
            //根据文件在服务器的路径读取该文件转化为流
            File file = new File(serverPath);
            inputStream = new FileInputStream(file);
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");

            out = response.getOutputStream();
            int b = 0;
            while (b != -1) {
                b = inputStream.read(buffer);
                //写到输出流(out)中
                out.write(buffer, 0, b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void downloadNewExcel(Integer id, HttpServletResponse response) {
        //文件在服务器的路径
        ExportRecord exportRecord = exportRecordMapper.selectByPrimaryKey(id);
        if (null == exportRecord) {
            throw  new ApiException("下载失败！");
        }
        String serverPath = exportRecord.getFileUrl();
        InputStream inputStream = null;
        OutputStream out = null;
        try {
            //根据文件在服务器的路径读取该文件转化为流
            URL realUrl = new URL(serverPath);
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Referer", "admin"); // 设置请求头
            connection.connect();
            inputStream = connection.getInputStream();

//            URL realUrl = new URL(serverPath);
//             inputStream = realUrl.openStream();

//            File file = new File(serverPath);
//            inputStream = new FileInputStream(file);
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + exportRecord.getFileName());
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.addHeader("Referer", "admin");

            out = response.getOutputStream();
            int b = 0;
            while (b != -1) {
                b = inputStream.read(buffer);
                //写到输出流(out)中
                out.write(buffer, 0, b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public CommonResult reissueLogCheck(String childOrderNo,Integer type) {
        String message = "";
        if(type == 1){
            List<ReissueLogistics> reissueLogistics = reissueLogisticsDao.selectByChildOrderNo(childOrderNo);
            if(reissueLogistics.size() > 0){
                message = "该订单已有补单记录，确认是否需申请售后退款，是否同步到退货管理！";
            }
        }else if(type == 2){
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andChildOrderNoEqualTo(childOrderNo).andOrderinfoStatusEqualTo("6");
            List<OrdersInfo> ordersInfos = ordersInfoMapper.selectByExample(ordersInfoExample);
            if(ordersInfos.size() > 0){
                message = "该订单已发起售后，是否继续提交补单！";
            }
        }else {
            throw new ApiException("来源类型出错！");
        }
        return CommonResult.success(message);
    }

    @Override
    public void exportExceptionOrders(HttpServletResponse response, ExceptionOrdersRequest exceptionOrdersRequest) {
        exceptionOrdersRequest.setRequestType(1);
        exceptionOrdersRequest.setPageHelper(1);
        String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/getAllExceptionOrders",
                JSONObject.toJSONString(exceptionOrdersRequest), supplyApiConfig.getHeadsMap());
        CommonResult commonResult = JSONObject.parseObject(result, CommonResult.class);
        if(commonResult.getCode() != 200){
            throw new ApiException("导出异常:"+commonResult.getMessage());
        }
        List<OrdersExceptionExcel> ordersExceptionExcels = JSONArray.parseArray(com.gexin.fastjson.JSON.toJSONString(commonResult.getData()),OrdersExceptionExcel.class) ;
        ordersExceptionExcels.stream().forEach(e->{
            if(e.getStatus() == 2){
                e.setStatusText("已处理");
            }else if(e.getStatus() == 1){
                e.setStatusText("未处理");
            }
            if(e.getIsFinished() == 1){
                e.setNotShow("是");
            }
            //处理快递流水
            String expressRecord = e.getExpressRecord();
            try {
                List<QueryTrackData> data = JSONArray.parseArray(expressRecord, QueryTrackData.class);
                if (!CollectionUtils.isEmpty(data)){
                    QueryTrackData queryTrackData = data.get(0);
                    expressRecord = queryTrackData.getFtime()+" "+queryTrackData.getContext();
                }
            } catch (Exception ex) {
                expressRecord = e.getExpressRecord();
            }
            e.setExpressRecord(expressRecord);
        });
        try {
            String fileName = "异常订单.xls";
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            // 设置背景颜色
            headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            // 设置头字体
            WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short) 14);
            // 字体加粗
            headWriteFont.setBold(true);
            headWriteCellStyle.setWriteFont(headWriteFont);
            // 设置头居中
            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

            // 内容策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            // 设置内容字体
            WriteFont contentWriteFont = new WriteFont();
            contentWriteFont.setFontHeightInPoints((short) 12);
            contentWriteFont.setFontName("宋体");
            contentWriteCellStyle.setWriteFont(contentWriteFont);
            // 设置 水平居中
//            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            // 设置 垂直居中
//            contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            // 设置单元格格式为 文本
            contentWriteCellStyle.setDataFormat((short) 49);

            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            // 设置表名，引脚名，文件格式，list数据
            EasyExcel.write(response.getOutputStream(),OrdersExceptionExcel.class)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .registerWriteHandler(new SpinnerWriteHandler())
                    .sheet("异常订单")
                    .doWrite(ordersExceptionExcels);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public CommonResult<List<ImportExcelFailResponse>> batchInsertNote(MultipartFile file) {
        Admin admin = UserUtil.getAdmin();
        // 解析
        Sheet sheet = new Sheet(1, 1, ImportBankerNoteRequest.class);
        List<String> isShowList = Arrays.asList("是", "否");
        List<ImportExcelFailResponse> dealOrdersFail = new ArrayList<>();
        try {
            List<Object> list = EasyExcelFactory.read(new BufferedInputStream(file.getInputStream()), sheet);
            log.info("表格数据：{}", JSONObject.toJSONString(list));
            List<ExceptionOrdersRequest> requests = new ArrayList<>();
            for (Object o : list) {
                ImportExcelFailResponse failResponse = new ImportExcelFailResponse();
                ImportBankerNoteRequest importBankerNoteRequest = (ImportBankerNoteRequest) o;
                Integer id = importBankerNoteRequest.getId();
                String statusText = importBankerNoteRequest.getStatusText();
                String remark = importBankerNoteRequest.getRemark();
                String notShow = importBankerNoteRequest.getNotShow();
                String finishedRemarks = importBankerNoteRequest.getFinishedRemarks();
                String supervisorNote = importBankerNoteRequest.getSupervisorNote();
                String handleNote = importBankerNoteRequest.getHandleNote();
                //请求参数
                ExceptionOrdersRequest request = new ExceptionOrdersRequest();
                request.setId(id);
                request.setHandlePerson(admin.getName());
                request.setExceptionOrderNote(remark);
                if (!"已处理".equals(statusText) && StrUtil.isBlankIfStr(notShow) && StrUtil.isBlankIfStr(supervisorNote) && StrUtil.isBlankIfStr(remark)) {
                    continue;
                }
                //是否处理
                if ("已处理".equals(statusText)) {
                    request.setStatus((byte) 2);
                    request.setHandleNote(handleNote);
                }
                //是否完结
                if ("是".equals(notShow)) {
                    request.setIsFinished(1);
                    request.setFinishedRemarks(finishedRemarks);
                }
                request.setSupervisorNote(supervisorNote);
                requests.add(request);
            }
            if(requests.size() == 0){
                throw new ApiException("数据为空！");
            }
            int pageSize = 200;
            int count = requests.size();
            if(count < pageSize){
                List<ImportExcelFailResponse> responses = dealExceptionOrderByPage(requests);
                dealOrdersFail.addAll(responses);
            }else {
                // 计算总页数
                int pages = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
                for (int pageNum = 0; pageNum < pages; pageNum++) {
                    // 起始位置
                    int start = pageNum == 0 ? 0 : pageNum * pageSize;
                    // 终止位置
                    int end = (pageNum + 1) * pageSize >= count ? count : (pageNum + 1) * pageSize;
                    List<ExceptionOrdersRequest> req = requests.subList(start, end);
                    List<ImportExcelFailResponse> responses = dealExceptionOrderByPage(req);
                    dealOrdersFail.addAll(responses);
                }
            }
            return CommonResult.success(dealOrdersFail);
        } catch (Exception e) {
            log.info("导入发生异常：{}", e.getMessage());
            return CommonResult.failed(e.getMessage());
        }
    }

    public List<ImportExcelFailResponse> dealExceptionOrderByPage(List<ExceptionOrdersRequest> requests){
        String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/updateExceptionHandleStatus",
                JSONObject.toJSONString(requests), supplyApiConfig.getHeadsMap());
        CommonResult commonResult = JSONObject.parseObject(result, CommonResult.class);
        if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
            throw new ApiException("接口出错！");
        } else if (200 != commonResult.getCode()) {
            throw new ApiException(commonResult.getMessage());
        } else {
            List<ImportExcelFailResponse> importExcelFailResponses = JSON.parseArray(JSON.toJSONString(commonResult.getData()), ImportExcelFailResponse.class);
            return importExcelFailResponses;
        }
    }

    @Override
    public CommonResult batchDealExceptionOrders(Integer[] ids,Integer type){
        if(null == type){
            throw new ApiException("请选择异常分类！");
        }
        String classifyName = ExceptionOrderClassifyEnum.getClassifyNameByType(type);
        if(StringUtils.isEmpty(classifyName)){
            throw new ApiException("您选择的异常分类不存在！");
        }
        List<ExceptionOrdersRequest> exceptionOrdersRequests = new ArrayList<>();
        for (Integer id : ids) {
            ExceptionOrdersRequest exceptionOrdersRequest = new ExceptionOrdersRequest();
            exceptionOrdersRequest.setId(id);
            exceptionOrdersRequest.setExceptionClassify(type.toString());
            exceptionOrdersRequest.setExceptionClassifyName(classifyName);
            exceptionOrdersRequests.add(exceptionOrdersRequest);
        }
        if(!CollectionUtils.isEmpty(exceptionOrdersRequests)){
            String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/updateExceptionHandleStatus",
                    JSONObject.toJSONString(Lists.newArrayList(exceptionOrdersRequests)), supplyApiConfig.getHeadsMap());
            CommonResult commonResult = JSONObject.parseObject(result, CommonResult.class);
            if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
                throw new ApiException("接口出错！");
            } else if (200 != commonResult.getCode()) {
                throw new ApiException(commonResult.getMessage());
            } else {
                List<ImportExcelFailResponse> importExcelFailResponses = JSON.parseArray(JSON.toJSONString(commonResult.getData()), ImportExcelFailResponse.class);
                if(!CollectionUtils.isEmpty(importExcelFailResponses)){
                    return CommonResult.failed(JSON.toJSONString(importExcelFailResponses));
                }
            }
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<List<ImportExcelFailResponse>> showExceptionOrders(ExceptionOrdersRequest request){
        Admin admin = UserUtil.getAdmin();
        if(StringUtils.isEmpty(request.getFinishedRemarks())){
            throw new ApiException("完结备注不能为空！");
        }
        ExceptionOrdersRequest exceptionOrders = new ExceptionOrdersRequest();
        exceptionOrders.setId(request.getId());
        exceptionOrders.setIsFinished(1);
        exceptionOrders.setHandlePerson(admin.getName());
        exceptionOrders.setStatus((byte) 2);
        exceptionOrders.setHandleNote(request.getFinishedRemarks());
        exceptionOrders.setFinishedRemarks(request.getFinishedRemarks());
        String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/updateExceptionHandleStatus",
                JSONObject.toJSONString(Lists.newArrayList(exceptionOrders)), supplyApiConfig.getHeadsMap());
        CommonResult commonResult = JSONObject.parseObject(result, CommonResult.class);
        if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
            throw new ApiException("接口出错！");
        } else if (200 != commonResult.getCode()) {
            throw new ApiException(commonResult.getMessage());
        } else {
            List<ImportExcelFailResponse> importExcelFailResponses = JSON.parseArray(JSON.toJSONString(commonResult.getData()), ImportExcelFailResponse.class);
            if(!CollectionUtils.isEmpty(importExcelFailResponses)){
                return CommonResult.failed(JSON.toJSONString(importExcelFailResponses));
            }
        }
        return CommonResult.success();
    }

    @Override
    public String createWxBill(PayBillRequest request){
        //支付单号在微信交易账单所在列的下标，从0开始
        final int PAY_NO_INDEX = 6;
        //交易状态在微信交易账单所在列的下标，类型有：SUCCESS、REFUND 等
        final int TRADE_TYPE_INDEX = 9;
        String timeDate = request.getTimeDate();
//        //解析微信账单后重新生成文件的文件名
        String childFileName = request.getPlatform() + "_" + request.getAccount() + System.currentTimeMillis() + "_" + timeDate + ".xlsx";
        //获取微信配置信息
        PayConfig payConfig = payConfigDao.getOnePayConfigByMchId(request.getAccount(), null);
        WxPayService wxPayService = WxPayServiceUtil.getWxBillService(payConfig);
        wxPayService.getConfig().setPrivateKeyPath(payConfig.getPrivateKeyPath());
        wxPayService.getConfig().setCertSerialNo(payConfig.getCertSerialNo());
        wxPayService.getConfig().setApiV3Key(payConfig.getWxKey());
        try {
            //下载账单分2步：
            //1.申请交易账单
            JSONObject billUrlJson = WxpayV3Util.tradebill(timeDate, wxPayService.getConfig(),request.getBillType());
            //2.下载对账单
            InputStream inputStream = WxpayV3Util.downloadBill(billUrlJson.toJSONString(), wxPayService.getConfig());

/*            //本地文件测试
            String inputFilePath = "D:\\cjw\\exportExcel\\jiaoyizhangdan.txt";
            FileInputStream inputStream = new FileInputStream(inputFilePath);*/
            //需要解析的数据集合
            List<List<String>> data = new ArrayList<>();
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            while ((line = br.readLine()) != null) {
                //如果每行是以字符 ,` 结尾,说明当前值是空值。
                line = line.endsWith(",`") ? line + " " : line;
                // 按逗号分隔每一列的数据
                String[] split = line.split(",`");
                //去除首尾空格,和指定符号
                List<String> row = new ArrayList<>(Arrays.asList(split).stream().map(e->e.trim().replace("`","")).collect(Collectors.toList()));
                //每行追加4列数据
                for (int i = 0; i < 5; i++) {
                    row.add("");
                }
                data.add(row);
            }
            if (br != null) {
                br.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
            if (!CollectionUtils.isEmpty(data)) {
                //excel所有总数据集合
                List<List<String>> totalRowData = new ArrayList();
                //excel头部列增加字段
                String[] strings = data.get(0).get(0).split(",");
                List<String> headData = new ArrayList<>(Arrays.asList(strings));
                headData.add("商品供货价");
                headData.add("商品运费");
                headData.add("总成本");
                headData.add("系统备注");
                headData.add("子订单号");
                totalRowData.add(headData);
                //解析出错标记
                AtomicReference<String> errorMsg = new AtomicReference<>();
                //订单数据,大于3则说明有订单数据
                if (data.size() > 3) {
                    //订单数据集合
                    List<List<String>> orderDataRow = data.subList(1, data.size() - 2);
                    // 分批次,多线程处理
                    // 每批批次大小
                    int batchSize = 1000;
                    // 获取数据总数
                    int totalCount = orderDataRow.size();
                    // 计算需要分批的次数
                    int batchCount = (totalCount + batchSize - 1) / batchSize;
                    CountDownLatch countDownLatch = new CountDownLatch(batchCount);
                    for (int i = 0; i < batchCount; i++) {
                        int finalI = i;
                        pools.execute(() -> {
                            try {
                                int startIndex = finalI * batchSize;
                                int endIndex = Math.min(startIndex + batchSize, totalCount);
                                List<List<String>> batchData = orderDataRow.subList(startIndex, endIndex);
                                //支付单号
                                List<String> resOrderNos = batchData.stream().map(e -> e.get(PAY_NO_INDEX)).collect(Collectors.toList());
                                List<OrderPayInfoResponse> list = ordersDao.getPayInfoByPayNo(resOrderNos);
                                Map<String, OrderPayInfoResponse> orderPayMap = list.stream().collect(Collectors.toMap(OrderPayInfoResponse::getResOrderNo, Function.identity(),(existing, replacement) -> existing));
                                for (List<String> rowData : batchData) {
                                    //获列数据：取业务凭证号
                                    String payNo = rowData.get(PAY_NO_INDEX);
                                    OrderPayInfoResponse orderPay = orderPayMap.get(payNo);
                                    if (orderPay != null) {
                                        log.info("====正在处理微信账单数据====》payNo:" + payNo);
                                        rowData.set(31, orderPay.getChildOrderNo());
                                        BigDecimal costPrice = orderPay.getCostPrice() == null ? BigDecimal.ZERO : orderPay.getCostPrice();
                                        BigDecimal freight = orderPay.getFreight() == null ? BigDecimal.ZERO : orderPay.getFreight();
                                        //当前业务类型
                                        String tradeType = rowData.get(TRADE_TYPE_INDEX);
                                        //针对不同的业务类型订单处理
                                        if ("SUCCESS".equals(tradeType)) {//支付订单
                                            //若果是重复支付的订单不计算成本价
                                            if (!orderPay.getTradeNo().equals(payNo)) {
                                                rowData.set(27, "0");
                                                rowData.set(28, "0");
                                                rowData.set(29, "0");
                                                rowData.set(30, "重复支付！");
                                            } else {
                                                rowData.set(27, costPrice.toPlainString());
                                                rowData.set(28, orderPay.getFreight().toPlainString());
                                                rowData.set(29, costPrice.add(freight).toPlainString());
                                            }
                                        } else if (Arrays.asList("REVOKED", "REFUND").contains(tradeType)) {// 退款/撤销订单
                                            // 若果是重复支付的订单退款或者撤销，不计算成本价
                                            if (!orderPay.getTradeNo().equals(payNo)) {
                                                rowData.set(27, "0");
                                                rowData.set(28, "0");
                                                rowData.set(29, "0");
                                                rowData.set(30, "重复支付退款！");
                                            } else {
                                                rowData.set(27, costPrice.toPlainString());
                                                rowData.set(28, orderPay.getFreight().toPlainString());
                                                rowData.set(29, costPrice.add(freight).toPlainString());
                                            }
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                errorMsg.set("解析微信账单商品信息出错" + e.getMessage());
                                log.error("解析微信账单商品信息出错！", e);
                            } finally {
                                countDownLatch.countDown();
                            }
                        });
                    }
                    countDownLatch.await();
                    //增加订单行数据
                    totalRowData.addAll(orderDataRow);
                }
                //追加最后两行汇总数据
//                totalRowData.addAll(data.subList(data.size() - 2, data.size()));
                if(StringUtils.isEmpty(errorMsg.get())){
                    EasyExcel.write(path + childFileName, null).excelType(ExcelTypeEnum.XLSX).sheet("微信交易账单"+timeDate).doWrite(totalRowData);
                }else {
                    log.error("解析微信账单出错===》", errorMsg.get());
                    childFileName = null;
                }
            }
        } catch (Exception e) {
            childFileName = null;
            log.error("获取微信账单出错===》", e);
        }
        return childFileName;
    }

    @Override
    public CommonResult exportFundBill(PayBillRequest request){
        Admin admin = UserUtil.getAdmin();
        CommonResult result = null;
        String timeDate = request.getTimeDate();
        if ((null == request.getTimeDateMark() || request.getTimeDateMark() == 0) && StringUtils.isEmpty(timeDate)) {
            throw new ApiException("账单时间不能为空");
        }
        if (null != request.getTimeDateMark() && request.getTimeDateMark() == 1 && (StringUtils.isEmpty(request.getStartTimeDate()) || StringUtils.isEmpty(request.getEndTimeDate()))) {
            throw new ApiException("账单时间区间必填！");
        }
        List<String> timeArray = new ArrayList<>();
        //时间条件
        String dateString = "";
        if (null == request.getTimeDateMark() || request.getTimeDateMark() == 0) {
            timeArray.add(request.getTimeDate());
            dateString = request.getTimeDate();
        }else if (request.getTimeDateMark() == 1){
            dateString = request.getStartTimeDate() + "~" + request.getEndTimeDate();
            LocalDate startDate = LocalDate.parse(request.getStartTimeDate());
            LocalDate endDate = LocalDate.parse(request.getEndTimeDate());
            List<LocalDate> datesBetween = DateUtils.getDatesBetween(startDate, endDate);
            for (LocalDate localDate : datesBetween) {
                timeArray.add(localDate.toString());
            }
        } else {
            throw new ApiException("账单时间格式不正确！");
        }
        //解析微信账单后重新生成文件的文件名
        String fileName = request.getPlatform() + "_" + dateString + ".xlsx";
        //记录导出文件
        BillExportRecord billExportRecord = new BillExportRecord();
        billExportRecord.setFileName(fileName);
        billExportRecord.setBillType(request.getPlatform());
        billExportRecord.setCreateTime(new Date());
        billExportRecord.setStatus(0);
        billExportRecord.setCreateAdminId(admin.getId());
        billExportRecordMapper.insert(billExportRecord);
        List<String> childFileNames = new ArrayList<>();
        for (String date : timeArray) {
            String childFileName = "";
            request.setTimeDate(date);
            if("wx".equals(request.getPlatform())){
                childFileName =  createWxBill(request);
            }else if("alipay".equals(request.getPlatform())){
                childFileName = createAlipayBill(request);
            }else {
                throw new ApiException("收款平台有误！");
            }
            if(!StringUtils.isEmpty(childFileName)){
                childFileNames.add(childFileName);
            }
        }
        //更新文件名称
        BillExportRecord newEntity = new BillExportRecord();
        newEntity.setId(billExportRecord.getId());
        newEntity.setStatus(1);
        newEntity.setChildFileName(String.join(",", childFileNames));
        //如果是跨日期账单,需要将多天账单合并
        if (timeArray.size() > 1) {
            try {
                newEntity.setChildFileName(String.join(",", childFileNames));
                if ("wx".equals(request.getPlatform())) {
                    batchDealWxExcel(childFileNames, fileName);
                } else if ("alipay".equals(request.getPlatform())) {
                    batchDealAlipayExcel(childFileNames, fileName);
                }
            } catch (Exception e) {
                newEntity.setStatus(2);
            }
        }else if(childFileNames.size() == 0){
            newEntity.setChildFileName(null);
            newEntity.setStatus(2);
        }
        billExportRecordMapper.updateByPrimaryKeySelective(newEntity);
        pools.execute(()->{
            delBillFile();
        });
        return result;
    }

    /**
     * 批量处理支付宝多个excel
     */
    public void batchDealAlipayExcel(List<String> childFileNames,String fileName) throws Exception{
        // 新建一个 ExcelWriter 对象，用于写入数据到新的 Excel 文件
        ExcelWriter excelWriter = EasyExcel.write(path + fileName).build();
        for (int i = 0; i < childFileNames.size(); i++) {
            String childFileName = childFileNames.get(i);
            // 定义集合列表，用于存储每一列的数据
            List<List<String>> allColumnData = new ArrayList<>();
            String inputFilePath = path + childFileName;
            // 定义一个事件监听器，用于处理读取的每一行数据
            int finalI = i;
            AnalysisEventListener<Map<Integer, String>> listener = new AnalysisEventListener<Map<Integer, String>>() {
                @Override
                public void invoke(Map<Integer, String> data, AnalysisContext context) {
                    Integer currentRowNum = context.readRowHolder().getRowIndex();
                    log.info("========>当前的行：" + currentRowNum);
                    List<String> rowData = new ArrayList<>();
                    //设置表头
                    if (finalI == 0 && currentRowNum == 4) {
                        // 遍历每一列的数据
                        for (Map.Entry<Integer, String> entry : data.entrySet()) {
                            rowData.add(entry.getValue());
                        }
                        allColumnData.add(rowData);
                    }
                    if (currentRowNum > 4) {
                        for (Map.Entry<Integer, String> entry : data.entrySet()) {
                            rowData.add(entry.getValue());
                        }
                        allColumnData.add(rowData);
                    }
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 所有数据读取完成后的操作
                    System.out.println("All data has been read.");
                    // 将集合列表中的数据写入新的 Excel 文件
                    WriteSheet writeSheet = EasyExcel.writerSheet().build();
                    excelWriter.write(allColumnData, writeSheet);
                }
            };
            // 使用 EasyExcel 读取 Excel 文件
            EasyExcel.read(inputFilePath, listener).sheet().doRead();
//            System.out.println(allColumnData);
        }
        // 最后，关闭 ExcelWriter
        excelWriter.finish();
        //删除子文件
        delBillByFiles(childFileNames);
    }
    /**
     * 批量处理微信多个excel
     */
    public void batchDealWxExcel(List<String> childFileNames, String fileName) throws Exception {
        // 新建一个 ExcelWriter 对象，用于写入数据到新的 Excel 文件
        ExcelWriter excelWriter = EasyExcel.write(path + fileName).build();
        for (int i = 0; i < childFileNames.size(); i++) {
            String childFileName = childFileNames.get(i);
            // 定义集合列表，用于存储每一列的数据
            List<List<String>> allColumnData = new ArrayList<>();
            String inputFilePath = path + childFileName;
            int finalI = i;
            // 定义一个事件监听器，用于处理读取的每一行数据
            AnalysisEventListener<Map<Integer, String>> listener = new AnalysisEventListener<Map<Integer, String>>() {
                @Override
                public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
                    if (finalI == 0) {
                        //设置表头
                        List<String> rowData = new ArrayList<>();
                        for (Map.Entry<Integer, CellData> entry : headMap.entrySet()) {
                            CellData value = entry.getValue();
                            rowData.add(value.getStringValue());
                        }
                        allColumnData.add(rowData);
                    }
                }

                @Override
                public void invoke(Map<Integer, String> data, AnalysisContext context) {
                    List<String> rowData = new ArrayList<>();
                    // 遍历每一列的数据
                    for (Map.Entry<Integer, String> entry : data.entrySet()) {
                        rowData.add(entry.getValue());
                    }
                    // 将每一行的数据添加到集合列表
                    allColumnData.add(rowData);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 所有数据读取完成后的操作
                    System.out.println("All data has been read.");
                    // 将集合列表中的数据写入新的 Excel 文件
                    WriteSheet writeSheet = EasyExcel.writerSheet().build();
                    excelWriter.write(allColumnData, writeSheet);
                }
            };
            // 使用 EasyExcel 读取 Excel 文件
            EasyExcel.read(inputFilePath, listener).sheet().doRead();
            System.out.println(allColumnData);
        }
        // 最后，关闭 ExcelWriter
        excelWriter.finish();
        delBillByFiles(childFileNames);
    }

    @Override
    public String createAlipayBill(PayBillRequest request){
        //支付单号在支付宝资金账单所在列的下标，从0开始
        final int PAY_NO_INDEX = 2;
        //业务类型在支付宝资金账单所在列的下标，类型有：交易退款、在线支付 等
        final int BUSINESS_TYPE_INDEX = 10;
        //获取支付配置信息
        String account = request.getAccount();
        String timeDate = request.getTimeDate();
//        String[] appIdList = account.split(",");
//        if(null == appIdList || appIdList.length == 0){
//            throw new ApiException("支付宝收款账户未配置！");
//        }
//        //默认取第一个appID
//        String appId = appIdList[0];
//        //支付宝子账号
//        String[] configs = appId.split("-");
        //解析账单后重新生成文件的文件名
        String childFileName = request.getPlatform() + "_" + System.currentTimeMillis() + "_" + timeDate + ".xlsx";
        try {
            AlipayDataDataserviceBillDownloadurlQueryResponse alipayBillDownload = getAlipayBillDownload(timeDate, org.apache.commons.lang3.StringUtils.isEmpty(request.getBillType()) ? "signcustomer" : request.getBillType(), account);
            if (!"10000".equals(alipayBillDownload.getCode())) {
                throw new ApiException("获取支付宝账单失败！" + JSON.toJSONString(alipayBillDownload));
            }
            //账单地址
            String billDownloadUrl = alipayBillDownload.getBillDownloadUrl();
            log.info("======支付宝账单地址=====" + billDownloadUrl);
            URL url = new URL(billDownloadUrl);
            URLConnection connection = url.openConnection();
            InputStream inputStream = connection.getInputStream();
/*
                //本地文件测试
                String zipFilePath = "D:\\cjw\\exportExcel\\alipay_zijinzhangdan.csv.zip";
                InputStream inputStream = new FileInputStream(zipFilePath);*/

            ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream, String.valueOf(Charset.forName("GBK")));
            ZipArchiveEntry zipEntry;
            //限制解析文件数量
            int fileNum = 0;
            while ((zipEntry = zipInputStream.getNextZipEntry()) != null) {
                String entryName = zipEntry.getName();
                //压缩文件内有多个文件，排除汇总数据文件
                if (entryName.contains("(汇总)")) {
                    continue;
                }
                if (fileNum > 1) {
                    break;
                }
                fileNum++;
                log.info("======压缩包内当前解析的文件名：" + entryName);
                BufferedReader br = new BufferedReader(new InputStreamReader(zipInputStream, "GBK"));
                //待解析的数据集合
                List<List<String>> data = new ArrayList<>();
                String line;
                while ((line = br.readLine()) != null) {
                    //如果每行是以字符 ,` 结尾,说明当前值是空值。
                    line = line.endsWith(",") ? line + " " : line;
                    // 按逗号分隔每一列的数据
                    String[] split = line.split(",");
                    //去除首尾空格
                    List<String> row = new ArrayList<>(Arrays.asList(split).stream().map(String::trim).collect(Collectors.toList()));
                    //循环次数与增加的列一致
                    for (int i = 0; i < 7; i++) {
                        //追加列数据
                        row.add("");
                    }
                    data.add(row);
                }
                if (br != null) {
                    br.close();
                }
                if (!CollectionUtils.isEmpty(data)) {
                    //总数据
                    List<List<String>> totalRowData = new ArrayList();
                    //增加excel字段
                    List<String> strings = data.get(4);
                    strings.set(12, "商品供货价");
                    strings.set(13, "商品运费");
                    strings.set(14, "总成本");
                    strings.set(15, "系统备注");
                    strings.set(16, "子订单号");
                    strings.set(17, "支付单号");
                    strings.set(18, "商品名称");
                    totalRowData.addAll(data.subList(0, 5));
                    //解析出错标记
                    AtomicReference<String> errorMsg = new AtomicReference<>();
                    //订单数据,大于9则说明有订单数据
                    if (data.size() > 9) {
                        List<List<String>> orderDataRow = data.subList(5, data.size() - 4);
                        // 分批次,多线程处理
                        // 每批批次大小
                        int batchSize = 1000;
                        // 获取数据总数
                        int totalCount = orderDataRow.size();
                        // 计算需要分批的次数
                        int batchCount = (totalCount + batchSize - 1) / batchSize;
                        CountDownLatch countDownLatch = new CountDownLatch(batchCount);
                        for (int i = 0; i < batchCount; i++) {
                            int finalI = i;
                            pools.execute(() -> {
                                try {
                                    int startIndex = finalI * batchSize;
                                    int endIndex = Math.min(startIndex + batchSize, totalCount);
                                    List<List<String>> batchData = orderDataRow.subList(startIndex, endIndex);
                                    //支付单号
                                    List<String> resOrderNos = new ArrayList<>();
                                    //服务单号
                                    List<String> serviceNos = new ArrayList<>();
                                    //支付单号信息
                                    for (List<String> batchDatum : batchData) {
                                        String s = batchDatum.get(PAY_NO_INDEX);
                                        if (s.startsWith("PAY")) {
                                            resOrderNos.add(s);
                                        }
                                        if (s.startsWith("YB")) {
                                            serviceNos.add(s);
                                        }
                                    }
                                    //交易单
                                    Map<String, OrderPayInfoResponse> orderPayMap = new HashMap<>();
                                    if (!CollectionUtils.isEmpty(resOrderNos)) {
                                        List<OrderPayInfoResponse> payOrderList = ordersDao.getPayInfoByPayNo(resOrderNos);
                                        orderPayMap = payOrderList.stream().collect(Collectors.toMap(OrderPayInfoResponse::getResOrderNo, Function.identity(), (existing, replacement) -> existing));
                                    }
                                    //退款单
                                    Map<String, OrderPayInfoResponse> serviceMap = new HashMap<>();
                                    if (!CollectionUtils.isEmpty(serviceNos)) {
                                        List<OrderPayInfoResponse> serviceList = ordersDao.getPayInfoByServiceNos(serviceNos);
                                        serviceMap = serviceList.stream().collect(Collectors.toMap(OrderPayInfoResponse::getRefundNo, Function.identity(), (existing, replacement) -> existing));
                                    }

                                    for (List<String> rowData : batchData) {
                                        //获列数据：取业务凭证号
                                        String payNo = rowData.get(PAY_NO_INDEX);
                                        if (!payNo.startsWith("PAY") && !payNo.startsWith("YB")) {
                                            continue;
                                        }
                                        OrderPayInfoResponse orderPay = null;
                                        if (payNo.startsWith("PAY")) {
                                            orderPay = orderPayMap.get(payNo);
                                        } else if (payNo.startsWith("YB")) {
                                            orderPay = serviceMap.get(payNo);
                                            if (null != orderPay) {
                                                rowData.set(17, orderPay.getResOrderNo());
                                            } else {
                                                rowData.set(17, "未找到对应的支付单号！");
                                            }
                                        }
                                        if (orderPay != null) {
                                            log.info("====正在处理支付宝账单数据====》payNo:" + payNo);
                                            BigDecimal costPrice = orderPay.getCostPrice() == null ? BigDecimal.ZERO : orderPay.getCostPrice();
                                            BigDecimal freight = orderPay.getFreight() == null ? BigDecimal.ZERO : orderPay.getFreight();
                                            rowData.set(16, orderPay.getChildOrderNo());
                                            rowData.set(18, orderPay.getProductName());
                                            //当前业务类型
                                            String businessType = rowData.get(BUSINESS_TYPE_INDEX);
                                            //只处理交易退款和在线支付的订单
                                            if("在线支付".equals(businessType)){
                                                //如果没有支付单号，则有问题
                                                if(StringUtils.isEmpty(orderPay.getTradeNo())){
                                                    rowData.set(15, "支付单号不存在！无法匹配订单数据");
                                                }else if (!orderPay.getTradeNo().equals(payNo)) { //若果是重复支付的订单不计算成本价
                                                    rowData.set(12, "0");
                                                    rowData.set(13, "0");
                                                    rowData.set(14, "0");
                                                    rowData.set(15, "重复支付！");
                                                } else {
                                                    rowData.set(12, costPrice.toPlainString());
                                                    rowData.set(13, orderPay.getFreight().toPlainString());
                                                    rowData.set(14, costPrice.add(freight).toPlainString());
                                                }
                                            }else if("交易退款".equals(businessType)){
                                                //获取备注数据
                                                String alipayRemark = rowData.get(11);
                                                if(!StringUtils.isEmpty(alipayRemark) && alipayRemark.contains("重复支付 平台退款")){
                                                    rowData.set(12, "0");
                                                    rowData.set(13, "0");
                                                    rowData.set(14, "0");
                                                    rowData.set(15, "重复支付退款！");
                                                }else {
                                                    rowData.set(12, costPrice.toPlainString());
                                                    rowData.set(13, orderPay.getFreight().toPlainString());
                                                    rowData.set(14, costPrice.add(freight).toPlainString());
                                                }
                                            }
                                        }
                                    }
                                } catch (Exception e) {
                                    errorMsg.set("解析支付宝账单商品信息出错！" + e.getMessage());
                                    log.error("解析支付宝账单商品信息出错！", e);
                                } finally {
                                    countDownLatch.countDown();
                                }
                            });
                        }
                        countDownLatch.await();
                        //增加订单行数据
                        totalRowData.addAll(orderDataRow);
                    }
                    //追加最后两行汇总数据
//                    totalRowData.addAll(data.subList(data.size() - 4, data.size()));
                    if (StringUtils.isEmpty(errorMsg.get())) {
                        EasyExcel.write(path + childFileName, null).excelType(ExcelTypeEnum.XLSX).sheet("支付宝资金账单" + timeDate).doWrite(totalRowData);
                    } else {
                        childFileName = null;
                    }
                }
            }
            if (zipInputStream != null) {
                zipInputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (Exception e) {
            childFileName = null;
            log.error("解析支付宝账单出错===》", e);
        }
        return childFileName;
    }

    @Override
    public AlipayDataDataserviceBillDownloadurlQueryResponse getAlipayBillDownload(String dateTime, String billType,String zfbAccount) throws Exception {

        YxAlipayConfig yxAlipayConfig = payConfigDao.findAliPayByAccount(zfbAccount);
        AlipayClient alipayClient = alipayUtil.getAlipayClientByMysql(yxAlipayConfig);

//        AlipayClient alipayClient = alipayFactory.getBillAlipayClient(childId);
        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
        model.setBillType(billType);
        model.setBillDate(dateTime);
        request.setBizModel(model);
        AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);
        return response;
    }

    @Override
    public AlipayDataDataserviceBillDownloadurlQueryResponse alipayFunds(String dateTime,String billType){
        AlipayDataDataserviceBillDownloadurlQueryResponse response = null;
        try {
            AlipayClient alipayClient = alipayFactory.getBillAlipayClient("0");
            AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
            AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
            model.setBillType(billType);
            model.setBillDate(dateTime);
            request.setBizModel(model);
            response = alipayClient.execute(request);
            log.info("====支付宝账单====："+JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("查询对账单下载地址出错！", e);
        }
        return response;
    }

    @Override
    public CommonPage<PayBillResponse> getBillListByPage(PayBillRequest request) {
        PageHelper.startPage(request.getPageNum(), request.pageSize);
        List<PayBillResponse> billList = billExportRecordDao.getBillList(request);
        return CommonPage.restPage(billList);
    }

    @Override
    public void downloadBill(HttpServletResponse response, Integer id) {
        Admin admin = UserUtil.getAdmin();
        if (admin.getId() == null) {
            throw new ApiException("你无权限下载！");
        }
        BillExportRecord billExportRecord = billExportRecordMapper.selectByPrimaryKey(id);
        if (billExportRecord == null || StringUtils.isEmpty(billExportRecord.getChildFileName())) {
            throw new ApiException("文件不存在！");
        }
        String[] split = billExportRecord.getFileName().split("~");
        String fileName = "";
        //如果不是跨日期区间的导出，文件名是子文件名
        if (split.length == 1) {
            fileName = billExportRecord.getChildFileName();
        } else {//如果是跨日期区间的导出，文件名是主文件名
            fileName = billExportRecord.getFileName();
        }

        //根据文件在服务器的路径读取该文件转化为流
        File file = new File(path + fileName);
        if (file.exists()) {
            try (InputStream inputStream = new FileInputStream(file);
                 OutputStream out = response.getOutputStream()) {
                //创建一个Buffer字符串
                byte[] buffer = new byte[1024];
                response.setContentType("application/octet-stream;charset=ISO8859-1");
                response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                response.addHeader("Pargam", "no-cache");
                response.addHeader("Cache-Control", "no-cache");
                int b = 0;
                while (b != -1) {
                    b = inputStream.read(buffer);
                    //写到输出流(out)中
                    out.write(buffer, 0, b);
                }
            } catch (Exception e) {
                log.error("下载报销单出错！", e);
                throw new ApiException("下载报销单出错!");
            }
        } else {
            throw new ApiException("当前下载的文件不存在，或者已被清理!");
        }
    }


    @Override
    public Map<String, Object> getAllAccount() {
        Map<String,Object> accountMap = new HashMap<>();
        SysConfigRequest wxConfigRequest = new SysConfigRequest();
        wxConfigRequest.setParamKey("wxzf_account");
        //查询微信账号
        List<SysConfigResponse> wxConfigResponses = sysConfigDao.querySysConfigByEntity(wxConfigRequest);
        if (CollectionUtils.isEmpty(wxConfigResponses)) {
            throw new ApiException("平台账号不存在！");
        }
        List<SysConfigResponse> sysConfigResponse = wxConfigResponses;
        String[] split = sysConfigResponse.get(0).getParamValue().split(",");
        accountMap.put("wx", split);
        //查询支付宝账号
        SysConfigRequest sysConfigRequest = new SysConfigRequest();
        sysConfigRequest.setParamKey("zfb_account");
        //微信账号
        List<SysConfigResponse> zfbConfigResponses = sysConfigDao.querySysConfigByEntity(sysConfigRequest);
        if (!CollectionUtils.isEmpty(zfbConfigResponses)) {
            SysConfigResponse zfbConfigResponse = zfbConfigResponses.get(0);
            String paramValue = zfbConfigResponse.getParamValue();
            Map<String, String> map = JSON.parseObject(paramValue, Map.class);
            List<Map<String,String>> data = new ArrayList<>();
            for(Map.Entry<String, String> e : map.entrySet()){
                Map<String,String> item = new HashMap<>();
                item.put("account",e.getKey());
                item.put("config",e.getValue());
                data.add(item);
            }
            accountMap.put("alipay", data);
        }
        return accountMap;
    }

    /**
     * 根据文件名删除文件
     */
    public void delBillByFiles(List<String> childFileNames) {
        //删除子文件
        for (String childFileName : childFileNames) {
            // 转换为Path对象
            Path filePath = Paths.get(path + childFileName);
            // 检查文件是否存在
            if (Files.exists(filePath)) {
                // 检查文件是否可写
                if (Files.isWritable(filePath)) {
                    try {
                        // 删除文件
                        Files.delete(filePath);
                    } catch (IOException e) {
                        log.error("删除跨日期导出的子文件出错！");
                    }
                }
            }
        }
    }

    /**
     * 删除早期账单文件
     */
    public void delBillFile(){
        //查询3个月前的账单数据
        List<PayBillResponse> preBill = billExportRecordDao.getPreBill(3);
        try {
            for (PayBillResponse payBillResponse : preBill) {
                // 指定文件的路径
                String filePath = path + payBillResponse.getFileName();
                // 转换为Path对象
                Path path = Paths.get(filePath);
                // 检查文件是否存在
                if (Files.exists(path)) {
                    // 检查文件是否可写
                    if (Files.isWritable(path)) {
                        try {
                            // 删除文件
                            Files.delete(path);
                            BillExportRecord billExportRecord = new BillExportRecord();
                            billExportRecord.setId(payBillResponse.getId());
                            billExportRecord.setIsDeleted(1);
                            billExportRecordMapper.updateByPrimaryKeySelective(billExportRecord);
                            log.info("已删除服务器账单文件："+payBillResponse.getFileName());
                        } catch (IOException e) {
                            log.error("删除前期存储在服务器的账单文件出错！");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("删除前期存储在服务器的账单文件出错！");
        }
    }

    /**
     * 校验账单时间
     */
    public void checkDateTime(String timeDate){
        // 将日期字符串解析为 LocalDate 对象
        LocalDate date = LocalDate.parse(timeDate, DateTimeFormatter.ISO_LOCAL_DATE);
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 获取当前时间
        LocalTime currentTime = LocalTime.now();
        // 设置目标时间为9点
        LocalTime targetTime = LocalTime.of(9, 0);
        // 判断日期是否在今天之前
        if (today.minusDays(1).equals(date) && currentTime.isBefore(targetTime)) {
            throw new ApiException("昨天的账单请在9点后导出！");
        } else if (date.equals(today)) {
            throw new ApiException("今天的账单请在次日9点后导出！");
        }else if(date.isAfter(today)){
            throw new ApiException("账单日期必须小于当天！");
        }
    }

    @Override
    public boolean checkIsLimitRole() {
        boolean isLimitRole = false;
        try {
            String userId = UserUtil.getPrincipal();
            List<Role> role = adminService.getRoleByEmail(userId);
            log.info("====currentUserRoldId={},userId:{}", role.toString(),userId);
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(role) && !com.alibaba.excel.util.StringUtils.isEmpty(limitOrderMoneyRoleId)) {
                List<String> limitRoleIds = Arrays.asList(limitOrderMoneyRoleId.split(","));
                if (limitRoleIds.contains(String.valueOf(role.get(0).getId()))) {
                    isLimitRole = true;
                }
            }
        } catch (Exception e) {
            log.error("{}", e);
        }
        return isLimitRole;
    }

    public static void main(String[] args) {
        String line = "`2024-01-17 18:00:14,`wxc92bbc68819fed57,`1636507437,`0,`,`4200001925202401040102485953,`PAY2024010413360219474867,`osYMa6nLo7ITdTqyIzMrgvf0Q1R4,`MWEB,`REFUND,`PAB_DEBIT,`CNY,`0.00,`0.00,`50310208192024011704347444955,`YB2024011718001324180763,`69.00,`0.00,`ORIGINAL,`SUCCESS,`【保真音质】三代智能降噪蓝牙耳机 双麦高,`,`-0.37000,`0.54%,`0.00,`69.00,` ";
        // 按逗号分隔每一列的数据
        String[] split = line.split(",`");
//        String[] split = line.split(",`\\s*");
        //去除首尾空格
        List<String> row = new ArrayList<>(Arrays.asList(split).stream().map(e->e.trim().replace("`","")).collect(Collectors.toList()));
        row.forEach(System.out::println);

    }

}
